<?php

namespace App\Repositories;

use App\Enums\AnchorEnum;
use App\Enums\GiftEnum;
use App\Models\MainDB\Accompany\AccompanyUser;
use App\Models\MainDB\BusinessConfig;
use App\Models\MainDB\Friend;
use App\Models\MainDB\AccountLog;
use App\Models\MainDB\Region;
use App\Models\MainDB\RoomJoinTime;
use App\Models\MainDB\RoomOnlineUser;
use App\Models\MainDB\Streamer\StreamerLevel;
use App\Models\MainDB\User;
use App\Models\MainDB\UserData;
use App\Models\MainDB\UserDevice;
use App\Models\MainDB\UserLinkman;
use App\Models\MainDB\UserRecharge;
use App\Models\MainDB\WithdrawBlock;
use App\Repositories\Group\GroupFriendCardRepository;
use App\Repositories\Group\GroupMemberRepository;
use App\Services\Business\BusinessConfigService;
use App\Services\Tools\AmapService;
use App\Traits\Singleton;
use Carbon\Carbon;
use App\Enums\RoomEnum;
use App\Enums\TaskEnum;
use App\Enums\UserEnum;
use App\Enums\RewardEnum;
use App\Enums\ActionEnum;
use App\Enums\CatGameEnum;
use App\Traits\UserAction;
use App\Enums\RedisKeyEnum;
use App\Enums\ContentNameEnum;
use App\Enums\ContentTypeEnum;
use App\Jobs\Content\ContentJob;
use App\Services\Tools\MapService;
use App\Exceptions\BasicException;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\DB;
use App\Services\Tools\CurlService;
use App\Services\Tools\RedisService;
use App\Services\Tools\CommonService;
use App\Services\Tools\FilterService;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Config;
use App\Services\Tools\GeohashService;
use App\Services\Cache\UserCacheService;

//引入配置类

class UserRepository
{
    use UserAction, Singleton;

    private $uniqueIds = [];   //保存循环获取的所有用户id

    public function getNobilityRatio($user_id)
    {
        $ratio = RedisService::getUserNobilityValue($user_id, 'ratio');

        return $ratio > 0 ? $ratio : 0;
    }

    /**
     * 获取用户手机号
     *
     * @param string $user_id
     *
     * @return string
     */
    public function getUserMobile($user_id)
    {
        return app('model_user')->where(['user_id' => $user_id])->value('mobile');
    }

    /**
     * 获取用户手机号,隐藏中间四位
     *
     * @param string $user_id
     *
     * @return string
     */
    public function getUserPrivateMobile($user_id)
    {
        $mobile = $this->getUserMobile($user_id);
        if (!$mobile) {
            return '';
        }

        return substr_replace($mobile, '****', 3, 4);
    }

    /**
     * 获取用户等级
     *
     * @param string $user_id
     *
     * @return array
     */
    public function getUserRank($user_id)
    {
        return app('model_user')->where(['user_id' => $user_id])->value('rank_id');
    }

    /**
     * 获取主播的资质列表
     *
     * @param $user_id
     * @param $uid
     *
     * @return array
     * @throws BasicException
     */
    public function getAnchorList($user_id, $uid)
    {
        $user = app('model_user_data')->where('user_id', $user_id)->with(
            [
                'lisences' => function ($query) {
                    $query->where('status', 1)->with(
                        [
                            'lisence' => function ($query) {
                                $query->select('square_icon', 'lisence_id', 'lisence_name', 'status');
                            },
                        ]
                    )->with(
                        [
                            'tag' => function ($query) {
                                $query->select('tag_id', 'tag_name');
                            },
                        ]
                    )->select(
                        'id',
                        'lisence_id',
                        'user_id',
                        'unique_tag',
                        'price',
                        'unit',
                        'voice',
                        'duration',
                        'lisence_pic',
                        'order_num'
                    )->orderBy('order_num', 'desc');
                },
            ]
        )->select('user_id', 'head_picture', 'nickname', 'sex', 'signature', 'birthday')->first();
        //    }])->select('user_id','head_picture','nickname','sex','user_photo','signature','birthday','vedio','vedio_cover')->first();

        if (empty($user)) {
            throw new BasicException(30013);
        }

        $concern = 0;

        //查询在线用户数组
        $online_arr = UserCacheService::getOnlineUserArr();

        //查询关注关系
        if (!empty($uid)) {
            $user_concern = app('model_follow')->where(['user_id' => $uid, 'followed_user' => $user_id])->first();

            if (!empty($user_concern)) {
                $concern = 1;
            }
        }

        //查询用户的环信账号
        $emchat = app('model_user')->where('user_id', $user_id)->select('emchat_username')->first();
        $emchat_username = isset($emchat->emchat_username) ? $emchat->emchat_username : '';


        //查询总单量
        $total_order = app('model_user_lisence')->where('user_id', $user_id)->where('status', 1)->sum('order_num');

        $lisence_data = [];

        $lisence_pic_data = [];

        if (isset($user->lisences) && !empty($user->lisences)) {
            foreach ($user->lisences as &$val) {
                if (!env('YUTANG_IOS_VERIFY') || (isset($val->lisence->status) && $val->lisence->status == 1)) {
                    $lisence_data[] = [
                        'id' => isset($val->id) ? $val->id : 0,
                        'icon' => isset($val->lisence->square_icon) ? $val->lisence->square_icon : '',
                        'lisence_name' => isset($val->lisence->lisence_name) ? $val->lisence->lisence_name : '',
                        'lisence_id' => isset($val->lisence_id) ? $val->lisence_id : 0,
                        'voice' => isset($val->voice) ? $val->voice : '',
                        'duration' => isset($val->duration) ? $val->duration : 0,
                        'price' => isset($val->price) ? $val->price : 0,
                        'unit' => isset($val->unit) ? $val->unit : '',
                        'tag_name' => isset($val->tag->tag_name) ? $val->tag->tag_name : '',
                        'total_num' => isset($val->order_num) ? $val->order_num : 0,
                    ];

                    //组合lisence_pic数据
                    if (isset($val->lisence_pic) && (count($lisence_pic_data) < 6)) {
                        $lisence_pic_data[] = $val->lisence_pic;
                    }
                }
            }
        }

        if (functionLimit() || isQipaoPlanet()) {
            $lisence_data = [];
        }

        //修饰数据
        $data = [

            'user_data' => [
                'user_id' => $user->user_id,
                'avatar' => $user->head_picture,
                'nickname' => substr_format($user->nickname, 6),
                'total_num' => $total_order,
                'online' => in_array($user->user_id, $online_arr) ? 1 : 0,   //1在线0离线
                'concern' => $concern,                                        //0未关注1已关注
                //                'video' => [
                //                    'url' => !empty($user->vedio) ? $user->veddio : '',
                //                    'cover' => !empty($user->vedio_cover) ? $user->vedio_cover : '',
                //                ],
                //                'user_photo' => $user->user_photo,
                'sex' => $user->sex,
                'age' => birthToAge($user->birthday, true),
                'signature' => substr_format($user->signature, 12),
                'lisence_pics' => $lisence_pic_data,
                'emchat_username' => $emchat_username,
            ],

            'lisence_data' => $lisence_data,
        ];

        return $data;
    }


    /**
     * 获取用户下单页详情
     *
     * @param $id
     * @param $uid
     *
     * @return mixed
     * @throws BasicException
     */
    public function getAnchorDetail($id, $uid)
    {
        $user = app('model_user_lisence')->where('id', $id)->where('status', 1)
            ->withOnly('user_data', ['user_id', 'nickname', 'head_picture', 'sex'])
            ->withOnly('lisence', ['lisence_id', 'lisence_name'])
            ->withOnly('user', ['user_id', 'emchat_username'])
            ->select(
                'user_id',
                'lisence_pic',
                'price',
                'unit',
                'order_num',
                'score',
                'is_verify',
                'voice',
                'duration',
                'lisence_id',
                'tag_image',
                'tag_ids',
                'id',
                'memo'
            )
            ->first();

        if (empty($user)) {
            throw new BasicException(30014);
        }

        //查询关注关系
        $concern = 0;

        //查询关注关系
        if (!empty($uid)) {
            $user_concern = app('model_follow')->where(['user_id' => $uid, 'followed_user' => $user->user_id])->first();

            if (!empty($user_concern)) {
                $concern = 1;
            }
        }

        $comment_data = [];

        //查询一条评论
        $comment = app('model_lisence_comment')->where('ulisence_id', $id)->where('status', 1)
            ->withOnly('user_data',
                ['user_id', 'head_picture', 'nickname', 'birthday', 'sex'])
            ->with(
                [
                    'user' => function ($query) {
                        $query->select('user_id', 'nobility',
                            'rank_id')->with('nobility')->with('grade');
                    },
                ]
            )->select('add_time', 'grade', 'content', 'mark', 'user_id')
            ->orderBy('grade', 'asc')->orderBy('add_time', 'desc')->first();

        if (!empty($comment)) {
            $comment_data = [
                'add_time' => date('Y-m-d', $comment->add_time),
                'avatar' => isset($comment->user_data->head_picture) ? $comment->user_data->head_picture : '',
                'nickname' => isset($comment->user_data->nickname) ? substr_format(
                    $comment->user_data->nickname,
                    6
                ) : '',
                'age' => isset($comment->user_data->birthday) ? birthToAge(
                    $comment->user_data->birthday,
                    true
                ) : 0,
                'sex' => isset($comment->user_data->sex) ? $comment->user_data->sex : 1,
                'nobility' => isset($comment->user->nobility->image) ? $comment->user->nobility->image : '',
                'rank' => isset($comment->user->grade->grade) ? $comment->user->grade->grade : '',
                'content' => $comment->content,
                'mark' => $comment->mark,
                'grade' => $comment->grade,
                'rank_picture' => isset($comment->user->grade->head_picture) ? $comment->user->grade->head_picture : '',
            ];
        }

        //标签数组
        $tag_arr = [];

        //修饰tag_image
        if (isset($user->tag_ids) && !empty($user->tag_ids)) {
            $tags = explode(',', $user->tag_ids);
            $tag_arr = app('model_lisence_tag')->whereIn('tag_id', $tags)->pluck('tag_name', 'tag_id')->toArray();
        }

        $image_data = [];

        foreach (json_decode($user->tag_image) as $key => $val) {
            if (!isset($tag_arr[$key])) {
                continue;
            }

            if (is_array($val)) {
                $content = '';

                foreach ($val as $nal) {
                    if (!isset($tag_arr[$nal])) {
                        continue;
                    }

                    $content .= $tag_arr[$nal] . '  ';
                }
            } else {
                $content = isset($tag_arr[$val]) ? $tag_arr[$val] : $val;
            }

            $image_data[] = [
                'title' => $tag_arr[$key],
                'content' => $content,
            ];
        }

        $image_data[] = [
            'title' => '接单说明',
            'content' => $user->memo,
        ];

        $total_comment = app('model_lisence_comment')->where('ulisence_id', $id)->count();

        //组装数据
        $data = [
            'user_data' => [
                'user_id' => $user->user_id,
                'avatar' => isset($user->user_data->head_picture) ? $user->user_data->head_picture : '',
                'nickname' => isset($user->user_data->nickname) ? $user->user_data->nickname : '',
                'sex' => isset($user->user_data->sex) ? $user->user_data->sex : 1,
                'concern' => $concern,
                'emchat_username' => isset($user->user->emchat_username) ? $user->user->emchat_username : '',
            ],
            'lisence_data' => [
                'id' => $user->id,
                'lisence_name' => isset($user->lisence->lisence_name) ? $user->lisence->lisence_name : '',
                'lisence_pic' => $user->lisence_pic,
                'price' => $user->price,
                'unit' => $user->unit,
                'total_num' => $user->order_num,
                'score' => $user->score,
                'is_verify' => $user->is_verify,
                'duration' => $user->duration,
                'voice' => $user->voice,
                'tags' => $image_data,
            ],
            'comment_data' => empty($comment_data) ? null : $comment_data,
            'total_comment' => $total_comment,
        ];


        return $data;
    }


    /**
     * 获取用户某资质下的评论列表
     *
     * @param $param
     * @param $page
     * @param $perPage
     *
     * @return mixed
     */
    public function anchorCommentList($param, $page, $perPage)
    {
        $list = app('model_lisence_comment')->where('ulisence_id', $param['id'])->where('status', 1)
            ->withOnly('user_data',
                ['user_id', 'head_picture', 'nickname', 'birthday', 'sex'])
            ->with(
                [
                    'user' => function ($query) {
                        $query->select('user_id', 'nobility',
                            'rank_id')->with('nobility')->with('grade');
                    },
                ]
            )->select('add_time', 'grade', 'content', 'mark', 'user_id')
            ->orderBy('grade', 'asc')->orderBy('add_time', 'desc')->paginate($perPage,
                ['*'], '', $page);

        foreach ($list as &$val) {
            $val->add_time = date('Y-m-d', $val->add_time);
            $val->avatar = isset($val->user_data->head_picture) ? $val->user_data->head_picture : '';
            $val->nickname = isset($val->user_data->nickname) ? substr_format($val->user_data->nickname, 6) : '';
            $val->age = isset($val->user_data->birthday) ? birthToAge($val->user_data->birthday, true) : 0;
            $val->sex = isset($val->user_data->sex) ? $val->user_data->sex : 1;
            $val->nobility = isset($val->user->nobility->image) ? $val->user->nobility->image : '';
            $val->rank = isset($val->user->grade->grade) ? $val->user->grade->grade : '';
            $val->rank_picture = isset($val->user->grade->head_picture) ? $val->user->grade->head_picture : '';
            unset($val->user_data);
            unset($val->user);
        }

        return $list;
    }


    /**
     * 获取用户的资质价格数组
     *
     * @param $uid
     *
     * @return mixed
     */
    public function getAnchorLisenceArr($uid)
    {
        $list = app('model_user_lisence')->where(['user_id' => $uid, 'status' => 1, 'is_open' => 1])->select(
            'lisence_id',
            'id',
            'price',
            'unit'
        )
            ->withOnly('lisence', ['lisence_id', 'lisence_name', 'icon'])->get();

        foreach ($list as &$val) {
            $val->lisence_name = isset($val->lisence->lisence_name) ? $val->lisence->lisence_name : '';
            $val->icon = isset($val->lisence->icon) ? $val->lisence->icon : '';
            unset($val->lisence);
            unset($val->lisence_id);
        }

        //查询主播详情
        $user = app('model_user_data')->where('user_id', $uid)->withOnly('user', ['user_id', 'emchat_username'])
            ->select('head_picture', 'nickname', 'sex', 'user_id')->first();

        if (!empty($user)) {
            $user->emchat_username = isset($user->user->emchat_username) ? $user->user->emchat_username : '';
            unset($user->user);
            unset($user->user_id);
        }


        $data = [
            'user_data' => $user,
            'lisence_data' => $list,
        ];

        return $data;
    }


    /**
     * @param $uid
     *
     * @return mixed
     */
    public function userSkillList($uid)
    {
        if (functionLimit()) {
            return [];
        }

        $list = app('model_user_lisence')->where('user_id', $uid)->where('status', 1);

        if (env('YUTANG_IOS_VERIFY')) {
            $list = $list->whereHas(
                'lisence',
                function ($query) {
                    $query->where('status', 1)->select('lisence_id', 'lisence_name', 'square_icon');
                }
            );
        } else {
            $list = $list->withOnly('lisence', ['lisence_id', 'lisence_name', 'square_icon']);
        }

        $list = $list->withOnly('tag', ['tag_id', 'tag_name'])
            ->select('id', 'lisence_id', 'unique_tag', 'voice', 'duration', 'price', 'unit', 'order_num')
            ->get();

        foreach ($list as &$val) {
            $val->lisence_name = isset($val->lisence->lisence_name) ? $val->lisence->lisence_name : '';
            $val->icon = isset($val->lisence->square_icon) ? $val->lisence->square_icon : '';
            $val->tag_name = isset($val->tag->tag_name) ? $val->tag->tag_name : '';
            $val->total_num = $val->order_num;
            unset($val->order_num);
            unset($val->lisence);
            unset($val->tag);
            unset($val->unique_tag);
            unset($val->lisence_id);
        }

        return $list;
    }


    /**
     * 获取私聊内的订单状态
     *
     * @param $user_id
     * @param $uid
     *
     * @return array
     */
    public function getPrivateOrder($user_id, $uid)
    {
        $order = app('model_lisence_order')->whereIn('user_id', [$user_id, $uid])
            ->whereIn('uid', [$user_id, $uid])->whereIn('status',
                [1, 4, 5, 7, 8, 10])->withOnly(
                'lisence',
                [
                    'lisence_id',
                    'icon',
                    'lisence_name',
                ]
            )
            ->select(
                'order_id',
                'lisence_id',
                'status',
                'price',
                'unit',
                'order_num',
                'ulisence_id',
                'uid',
                'user_id',
                'add_time'
            )->orderBy('update_time', 'desc')
            ->first();
        //人脉CP申请，结婚申请列表
        $applyList = app('repo_connection')->privateChatApplyList($uid);
        $data = [
            'type' => -1,
            'data' => null,
        ];

        if (functionLimit()) {
            $data['apply_list'] = $applyList;

            return $data;
        }

        if (!empty($order) && ($order->user_id != $order->uid)) {
            $type = ($order->user_id == $uid) ? 1 : 2;  //1是用户视角2是大神视角

            //过期时间
            if ($order->status == 1) {
                $expire_time = $order->add_time + Config::get('qipao.const_number.order_expire_time');
            } elseif ($order->status == 4) {
                $expire_time = $order->add_time + Config::get('qipao.const_number.order_complete_time');
            } else {
                $expire_time = 0;
            }

            $data = [
                'type' => 1,
                'data' => [
                    'order_id' => $order->order_id,
                    'lisence_id' => $order->lisence_id,
                    'status' => $order->status,
                    'unit' => $order->unit,
                    'order_num' => $order->order_num,
                    'price' => $order->price,
                    'lisence_name' => isset($order->lisence->lisence_name) ? $order->lisence->lisence_name : '',
                    'icon' => isset($order->lisence->icon) ? $order->lisence->icon : '',
                    'expire_time' => $expire_time,
                    'type' => $type,
                    'ulisence_id' => $order->ulisence_id,
                ],
            ];
        } else {
            $user_lisence = app('model_user_lisence')->where('user_id', $user_id)->where('status', 1)->where(
                'is_open',
                1
            )
                ->withOnly('lisence',
                    ['lisence_id', 'icon', 'lisence_name'])->select(
                    'lisence_id',
                    'price',
                    'unit',
                    'id',
                    'add_time'
                )
                ->orderBy('update_time', 'desc')->first();

            if (!empty($user_lisence)) {
                $data = [
                    'type' => 0,
                    'data' => [
                        'lisence_id' => $user_lisence->lisence_id,
                        'id' => $user_lisence->id,
                        'lisence_name' => isset($user_lisence->lisence->lisence_name) ? $user_lisence->lisence->lisence_name : '',
                        'icon' => isset($user_lisence->lisence->icon) ? $user_lisence->lisence->icon : '',
                        'price' => $user_lisence->price,
                        'unit' => $user_lisence->unit,
                        'ulisence_id' => $user_lisence->id,
                    ],
                ];
            }
        }
        $data['apply_list'] = $applyList;

        return $data;
    }


    /**
     * 获取订单消息列表
     *
     * @param $uid
     * @param $page
     * @param $perPage
     *
     * @return mixed
     */
    public function getMessageList($uid, $page, $perPage)
    {
        $time = time();
        //刷成已读
        app('model_lisence_message')->where('user_id', $uid)->where('is_read', 0)->update(
            ['is_read' => 1, 'read_time' => $time]
        );

        $list = app('model_lisence_message')->where('user_id', $uid)->withOnly(
            'lisence',
            ['lisence_id', 'lisence_name', 'icon']
        )
            ->withOnly('user_data',
                ['user_id', 'head_picture', 'nickname'])->orderBy('ctime',
                'desc')->paginate(
                $perPage,
                ['*'],
                '',
                $page
            );

        foreach ($list as &$val) {
            $val->lisence_name = isset($val->lisence->lisence_name) ? $val->lisence->lisence_name : '';
            $val->icon = isset($val->lisence->icon) ? $val->lisence->icon : '';
            $val->nickname = isset($val->user_data->nickname) ? $val->user_data->nickname : '';
            $val->avatar = isset($val->user_data->head_picture) ? $val->user_data->head_picture : '';
            $val->ctime = date('m月d日 H:i', $val->ctime);
            $val->add_time = date('m月d日 H:i', $val->add_time);
            unset($val->user_data);
            unset($val->lisence);
            unset($val->user_id);
            unset($val->lisence_id);
            unset($val->update_time);
            unset($val->read_time);
            unset($val->ulisence_id);
        }

        return $list;
    }


    /**
     * 阅读订单消息
     *
     * @param $uid
     *
     * @return bool
     */
    public function readOrderMessage($uid)
    {
        $time = time();

        app('model_lisence_message')->where('user_id', $uid)->where('is_read', 0)->update(
            ['is_read' => 1, 'read_time' => $time]
        );

        return true;
    }

    public function getUserMoney($user_id)
    {
        $money = app('model_user')->where('user_id', $user_id)->value('money');

        return $money > 0 ? $money : 0;
    }

    //获取用户可用收益
    public function getUserEarnings($user_id)
    {
        $earnings = app('model_user')->where('user_id', $user_id)->value('earnings');

        return $earnings > 0 ? $earnings : 0;
    }

    public function updateUserMoney($data = [])
    {
        $user_id = $data['user_id'];
        $money = $data['money'];
        $abs_money = abs($money);
        $where['user_id'] = $user_id;
        if ($money < 0) {
            $where[] = ['money', '>=', $abs_money];
            $result = app('model_user')->where($where)->decrement('money', $abs_money);
        } else {
            $result = app('model_user')->where($where)->increment('money', $money);
        }

        return $result ? true : false;
    }

    public function incUserEarnings($userId, $earnings): bool
    {
        return $this->updateUserEarnings(["user_id" => $userId, "earnings" => $earnings]);
    }

    public function updateUserEarnings($data = [])
    {
        $user_id = $data['user_id'];
        $earnings = $data['earnings'];
        $abs_earnings = abs($earnings);
        $where['user_id'] = $user_id;
        if ($abs_earnings < 0) {
            $where[] = ['earnings', '>=', $abs_earnings];
            $result = app('model_user')->where($where)->decrement('earnings', $abs_earnings);
        } else {
            $result = app('model_user')->where($where)->increment('earnings', $abs_earnings);
        }

        return $result ? true : false;
    }

    /**
     * 发布动态
     *
     * @param $param
     *
     * @return bool
     * @throws BasicException
     */
    public function createMicroBlog($param = [])
    {
        $data = [
            'user_id' => UID,
            'add_time' => time(),
            'update_time' => time(),
        ];

        $ndata = array_merge($data, $param);

        $id = app('model_microblog')->insertGetId($ndata);
        if ($id) {
            return $id;
        }
        throw new BasicException(90024);
    }


    /**
     * 删除动态
     *
     * @param $id
     *
     * @return bool
     * @throws BasicException
     */
    public function deleteMicroBlog($id)
    {
        $blog = app('model_microblog')->where(['id' => $id, 'user_id' => UID])->first();

        if (empty($blog)) {
            throw new BasicException(30046);
        }

        if ($blog->status != 1) {
            throw new BasicException(30047);
        }

        $res = app('model_microblog')->where('id', $id)->update(['status' => 2, 'update_time' => time()]);

        if ($res) {
            return true;
        }

        throw new BasicException(90025);
    }


    /**
     * 动态列表
     *
     * @param     $user_id
     * @param int $page
     * @param int $perPage
     *
     * @return mixed
     */
    public function getMicroBlogList($param, $page = 1, $perPage = 15)
    {
        $list = app('model_microblog');

        //权限控制
        if ($param['user_id'] != UID) {
            //查询好友关系
            $friend = app('model_friend')->where(['user_id' => $param['user_id'], 'friend_id' => UID])->first();
            if (!empty($friend)) {
                $list = $list->whereIn('privacy', [1, 2]);
            } else {
                $list = $list->where('privacy', 1);
            }
        }

        $list = $list->where(['user_id' => $param['user_id'], 'status' => 1])->where('verify', 3)
            ->withOnly('user_data',
                ['user_id', 'nickname', 'head_picture', 'sex', 'birthday'])->with([
                'user' => function ($query) {
                    $query->select('user_id', 'rank_id', 'emchat_username')->withOnly('grade', ['id', 'head_picture']);
                },
            ])->select('id', 'user_id', 'content', 'img_arr', 'add_time', 'like_num', 'comment_num', 'position',
                'privacy', 'type', 'cover', 'extra')->orderBy('add_time',
                'desc')->paginate($perPage, ['*'], '', $page);

        //查询自己点赞动态的ID数组
        $like_arr = app('model_microblog_like')->where(['user_id' => UID, 'type' => 1])->pluck('blog_id')->toArray();

        //查询此人是否已经关注
        $concern = app('model_follow')->where(['user_id' => UID, 'followed_user' => $param['user_id']])->first();


        foreach ($list as &$val) {
            $val->add_time = (isset($val->add_time) && !empty($val->add_time)) ? format_time($val->add_time,
                true) : format_time(time(), true);
            $val->rank_pic = isset($val->user->grade->head_picture) ? $val->user->grade->head_picture : '';
            $val->emchat_username = isset($val->user->emchat_username) ? $val->user->emchat_username : '';
            $val->nickname = isset($val->user_data->nickname) ? $val->user_data->nickname : '';
            $val->head_picture = isset($val->user_data->head_picture) ? $val->user_data->head_picture : '';
            $val->sex = (isset($val->user_data->sex) && $val->user_data->sex == 1) ? $val->user_data->sex : 2;
            $val->age = isset($val->user_data->birthday) ? birthToAge($val->user_data->birthday, true) : 0;
            $val->is_like = in_array($val->id, $like_arr) ? 1 : 0;
            $val->is_concern = !empty($concern) ? 1 : 0;
            $val->extra = $val->extra ? json_decode($val->extra, true) : new \ArrayObject();
            $val->special = app('model_user')->special($val->user_id);
            unset($val->user);
            unset($val->user_data);
        }

        return $list;
    }


    /**
     * 获取签到进度/签到
     */
    public function signin(int $userId, int $type)
    {
        if (!in_array($type, [1, 2])) {
            return false;
        }
        $detail = app('model_user_signin')->where('user_id', $userId)->first();

        //bof 签到配置 by zhouliang
        $sign_config = app('model_config')->getValue('SIGN_REWARD_CONFIG');
        if (empty($sign_config)) {
            return false;
        }
        $list = [];
        foreach ($sign_config as $days => $reward) {
            [$r_id, $r_type, $r_number] = explode('-', $reward);
            $reward_result = app('repo_reward')->getRewardInfo($r_id, $r_type);
            $list[] = [
                'days' => $days,
                'cover_image' => $reward_result['picture'],
                'number' => $r_number * $reward_result['number'],
                'received' => false,
            ];
        }
        //eof
        if ($type == 1) {
            $result = [
                'allow_signin' => false,
                'list' => $list,
            ];
            if (empty($detail)) {
                $result['allow_signin'] = true;

                return $result;
            } else {
                foreach ($result['list'] as &$value) {
                    if ($detail->days >= $value['days']) {
                        $value['received'] = true;
                    }
                }
                if ($detail->days >= 7) {
                    return $result;
                }
                $date = date('Ymd', strtotime('-1 day'));
                if ($date == $detail->last_signin_date || $detail->last_signin_date == 0) {
                    $result['allow_signin'] = true;
                }

                return $result;
            }
        } else {
            if ($type == 2) {
                if (empty($detail)) {
                    $signinData = [
                        'user_id' => $userId,
                        'days' => 1,
                        'last_signin_date' => date('Ymd'),
                        'add_time' => date('Y-m-d H:i:s'),
                    ];
                    DB::beginTransaction();
                    try {
                        app('model_user_signin')->create($signinData);
                        //发放道具 by zhouliang
                        [$r_id, $r_type, $r_number] = explode('-', $sign_config[$signinData['days']]);
                        $r_number = $r_number > 0 ? $r_number : 1;
                        $rewards[] = [
                            'id' => $r_id,
                            'type' => $r_type,
                            'number' => $r_number,
                        ];
                        app('repo_reward')->setChannel(RewardEnum::REWARD_SOURCE_TYPE_SIGN);
                        app('repo_reward')->sendRewardAll($userId, $rewards);
                        $re = app('repo_reward')->getRewardDetail($r_id, $r_type, $r_number);
                        $reward_result = $re['list'];
                        DB::commit();
                    } catch (\Exception $e) {
                        DB::rollBack();
                        throw new BasicException(90020);
                    }
                } else {
                    if ($detail['last_signin_date'] == date('Ymd')) {
                        DB::rollBack();
                        throw new BasicException(70102);
                    }
                    $date = date('Ymd', strtotime('-1 day'));
                    $updateData['last_signin_date'] = date('Ymd');
                    if ($detail['last_signin_date'] == $date) {
                        $updateData['days'] = $detail->days + 1;
                    } else {
                        $updateData['days'] = 1;
                    }
                    DB::beginTransaction();
                    try {
                        app('model_user_signin')->where('id', $detail->id)->update($updateData);

                        //发放道具 by zhouliang
                        [$r_id, $r_type, $r_number] = explode('-', $sign_config[$updateData['days']]);
                        $r_number = $r_number > 0 ? $r_number : 1;
                        $rewards[] = [
                            'id' => $r_id,
                            'type' => $r_type,
                            'number' => $r_number,
                        ];
                        app('repo_reward')->setChannel(RewardEnum::REWARD_SOURCE_TYPE_SIGN);
                        app('repo_reward')->sendRewardAll($userId, $rewards);

                        $re = app('repo_reward')->getRewardDetail($r_id, $r_type, $r_number);
                        $reward_result = $re['list'];

                        DB::commit();
                    } catch (\Exception $e) {
                        DB::rollBack();
                        throw new BasicException(90020);
                    }
                }

                return $reward_result;
            }
        }
    }


    // 获取用户总的在房间中时长(秒)
    public function getUserStayInRoomDelay($userId)
    {
        $dbRes = app("model_room_stay_delay")
            ->where([
                ["is_deleted", 0],
                ["status", RoomEnum::ROOM_STAY_STATUS_HAS_LEAVE],
                ["user_id", $userId],
            ])
            ->sum("total_seconds");

        $totalSeconds = intval($dbRes);

        $dbRes = app("model_room_stay_delay")
            ->where([
                ["is_deleted", 0],
                ["status", RoomEnum::ROOM_STAY_STATUS_HAS_JOIN],
                ["user_id", $userId],
            ])
            ->orderBy("update_time", "desc")
            ->first();

        if ($dbRes && $dbRes->enter_time) {
            $totalSeconds = $totalSeconds + (time() - $dbRes->enter_time);
        }

        return $totalSeconds;
    }

    // 获取用户某日总的在房间中时长(秒)
    public function getUserStayInRoomDailyDelay($userId, $date)
    {
        $dateStartTime = strtotime($date);
        $dateEndTime = strtotime($date . " +1 days") - 1;

        $dbRes = app("model_room_stay_delay")
            ->where([
                ["is_deleted", 0],
                ["status", RoomEnum::ROOM_STAY_STATUS_HAS_LEAVE],
                ["user_id", $userId],
                ["enter_time", ">=", $dateStartTime],
                ["enter_time", "<=", $dateEndTime],
            ])
            ->sum("total_seconds");

        $totalSeconds = intval($dbRes);

        $dbRes = app("model_room_stay_delay")
            ->where([
                ["is_deleted", 0],
                ["status", RoomEnum::ROOM_STAY_STATUS_HAS_JOIN],
                ["user_id", $userId],
            ])
            ->orderBy("update_time", "desc")
            ->first();

        if ($dbRes && $dbRes->enter_time && $date == date("Y-m-d")) {
            if (time() > $dbRes->enter_time) {
                $totalSeconds = $totalSeconds + (time() - $dbRes->enter_time);
            }
        }
        if ($totalSeconds < 0) {
            file_put_contents(
                storage_path() . '/logs/' . date('Ymd') . '.log',
                json_encode(
                    [
                        'userId' => $userId,
                        'totalSeconds' => $totalSeconds,
                        'dbRes' => $dbRes,
                        'time' => date('Y-m-d H:i:s'),
                    ]) . PHP_EOL, FILE_APPEND
            );
        }

        return $totalSeconds;
    }

    // 获取用户参与小猫浇水次数
    public function getUserPlayCatWaterTimes($userId)
    {
        $dbRes = app("model_gold_price")
            ->where([
                ["game_type", CatGameEnum::CAT_GAME_TYPE_WATERING],
                ["user_id", $userId],
            ])
            ->sum("count");

        return intval($dbRes);
    }

    // 获取某天用户参与小猫浇水次数
    public function getUserPlayCatWaterDailyTimes($userId, $date)
    {
        $dateStartTime = strtotime($date);
        $dateEndTime = strtotime($date . " +1 days") - 1;

        $dbRes = app("model_gold_price")
            ->where([
                ["game_type", CatGameEnum::CAT_GAME_TYPE_WATERING],
                ["user_id", $userId],
                ["add_time", ">=", $dateStartTime],
                ["add_time", "<=", $dateEndTime],
            ])
            ->sum("count");

        return intval($dbRes);
    }

    // 获取用户累计登录天数
    public function getUserTotalLoginDays($userId)
    {
        $redisKey = sprintf(UserEnum::USER_LOGIN_DATE, $userId);
        $result = Redis::zcard($redisKey);

        return intval($result);
    }

    // 记录用户登录天
    public function addUserLoginDay($userId)
    {
        $redisKey = sprintf(UserEnum::USER_LOGIN_DATE, $userId);
        Redis::zadd($redisKey, date("Ymd"), date("Y-m-d"));

        Redis::expire($redisKey, UserEnum::USER_LOGIN_DATE_EXPIRE_TIME);

        return true;
    }

    // 用户某日是否登录过
    public function isUserHasLoginDay($userId, $date)
    {
        $redisKey = sprintf(UserEnum::USER_LOGIN_DATE, $userId);
        $res = Redis::zscore($redisKey, $date);
        if ($res === false || is_null($res)) {
            return false;
        }

        return true;
    }

    // 获取用户累计分享次数
    public function getUserTotalShareTimes($userId)
    {
        $redisKey = sprintf(UserEnum::USER_SHARE_TIMES, $userId);

        $result = Redis::get($redisKey);

        return intval($result);
    }

    // 记录用户分享次数
    public function addUserTotalShareTimes($userId)
    {
        $redisKey = sprintf(UserEnum::USER_SHARE_TIMES, $userId);

        $result = Redis::INCR($redisKey);

        return intval($result);
    }

    // 获取用户关注房间个数
    public function getUserFollowRoomNumber($userId)
    {
        $dbRes = app("model_room_favorite")
            ->where([
                ["user_id", $userId],
            ])
            ->count();

        return intval($dbRes);
    }

    // 获取某天用户关注房间个数
    public function getUserFollowRoomDailyNumber($userId, $date)
    {
        $dateStartTime = strtotime($date);
        $dateEndTime = strtotime($date . " +1 days") - 1;
        $dbRes = app("model_room_favorite")
            ->where([
                ["user_id", $userId],
                ["add_time", ">=", $dateStartTime],
                ["add_time", "<=", $dateEndTime],
            ])
            ->count();

        return intval($dbRes);
    }

    // 获取我关注的用户个数
    public function getUserFollowNumber($userId)
    {
        $dbRes = app("model_follow")->where('user_id', $userId)->count();

        return intval($dbRes);
    }

    // 获取我某天关注的用户个数
    public function getUserFollowDailyNumber($userId, $date)
    {
        $dateStartTime = strtotime($date);
        $dateEndTime = strtotime($date . " +1 days") - 1;
        $dbRes = app("model_follow")
            ->where([
                ["user_id", $userId],
                ["add_time", ">=", $dateStartTime],
                ["add_time", "<=", $dateEndTime],
            ])
            ->count();

        return intval($dbRes);
    }

    // 获取我的粉丝个数
    public function getUserFansNumber($userId)
    {
        $dbRes = app("model_follow")
            ->where([
                ["followed_user", $userId],
            ])
            ->count();

        return intval($dbRes);
    }

    // 获取我的好友个数
    public function getUserFriendNumber($userId)
    {
        $dbRes = app("model_friend")->where('user_id', $userId)->count();

        return intval($dbRes);
    }

    // 获取我今日新增的好友个数
    public function getUserFriendDailyNumber($userId, $date)
    {
        $dateStartTime = strtotime($date);
        $dateEndTime = strtotime($date . " +1 days") - 1;
        $dbRes = app("model_friend")
            ->where([
                ["user_id", $userId],
                ["add_time", ">=", $dateStartTime],
                ["add_time", "<=", $dateEndTime],
            ])
            ->count();

        return intval($dbRes);
    }

    // 获得用户公屏聊天次数
    public function getUserPublicChatTimes($userId)
    {
        $dbRes = app("model_chat")
            ->where([
                ["user_id", $userId],
                ["type", 1],
            ])
            ->count();

        return intval($dbRes);
    }

    // 获得某天用户公屏聊天次数
    public function getUserPublicChatDailyTimes($userId, $date)
    {
        $dateStartTime = strtotime($date);
        $dateEndTime = strtotime($date . " +1 days") - 1;
        $dbRes = app("model_chat")
            ->where([
                ["user_id", $userId],
                ["type", 1],
                ["add_time", ">=", $dateStartTime],
                ["add_time", "<=", $dateEndTime],
            ])
            ->count();

        return intval($dbRes);
    }

    // 获得用户送礼次数
    public function getUserSendGiftTimes($userId)
    {
        $dbRes = app("model_give_gift")
            ->where([
                ["user_id", $userId],
                ["gift_user", "<>", $userId],
            ])
            ->count();

        return intval($dbRes);
    }

    // 获得用户某日送礼次数
    public function getUserSendGiftDailyTimes($userId, $date)
    {
        $dateStartTime = strtotime($date);
        $dateEndTime = strtotime($date . " +1 days") - 1;
        $dbRes = app("model_give_gift")
            ->where([
                ["user_id", $userId],
                ["gift_user", "<>", $userId],
                ["add_time", ">=", $dateStartTime],
                ["add_time", "<=", $dateEndTime],
            ])
            ->count();

        return intval($dbRes);
    }

    // 获得用户收到礼物价值
    public function getUserReceiveGiftValue($userId)
    {
        $dbRes = app("model_give_gift")
            ->where([
                ["gift_user", $userId],
                ["user_id", "<>", $userId],
            ])
            ->sum("total_price");

        return floatval($dbRes);
    }

    // 获得用户某日收到礼物价值
    public function getUserReceiveGiftDailyValue($userId, $date)
    {
        $dateStartTime = strtotime($date);
        $dateEndTime = strtotime($date . " +1 days") - 1;
        $dbRes = app("model_give_gift")
            ->where([
                ["gift_user", $userId],
                ["user_id", "<>", $userId],
                ["add_time", ">=", $dateStartTime],
                ["add_time", "<=", $dateEndTime],
            ])
            ->sum("total_price");

        return floatval($dbRes);
    }

    // 用户是否已通过实名认证
    public function isAuth($userId)
    {
        $dbRes = app("model_user_auth")
            ->where([
                ["user_id", $userId],
                ["deleted", 0],
                ["app_status", UserEnum::USER_AUTH_STATUS_PASS],
            ])
            ->count();

        $count = intval($dbRes);

        return $count > 0;
    }

    // 用户是否已设置个性签名
    public function isSetSign($userId)
    {
        $dbRes = app("model_user_data")
            ->where([
                ["user_id", $userId],
            ])
            ->first();
        if (empty($dbRes['signature'])) {
            return false;
        }

        return true;
    }

    // 用户是否已创建房间
    public function isCreateRoom($userId)
    {
        $dbRes = app("model_user_room")
            ->where([
                ["user_id", $userId],
            ])
            ->first();
        if (empty($dbRes)) {
            return false;
        }

        return true;
    }

    // 获得用户充值次数
    public function getUserRechargeTimes($userId)
    {
        $dbRes = app("model_user_recharge")
            ->where([
                ["user_id", $userId],
                ["status", UserEnum::USER_RECHARGE_HAS_PAY],
            ])
            ->count();

        return intval($dbRes);
    }

    // 获得用户某日充值次数
    public function getUserRechargeDailyTimes($userId, $date)
    {
        $dateStartTime = strtotime($date);
        $dateEndTime = strtotime($date . " +1 days") - 1;
        $dbRes = app("model_user_recharge")
            ->where([
                ["user_id", $userId],
                ["status", UserEnum::USER_RECHARGE_HAS_PAY],
                ["add_time", ">=", $dateStartTime],
                ["add_time", "<=", $dateEndTime],
            ])
            ->count();

        return intval($dbRes);
    }

    // 获得用户充值金额
    public function getUserRechargeMoney($userId)
    {
        $dbRes = app("model_user_recharge")
            ->where([
                ["user_id", $userId],
                ["status", UserEnum::USER_RECHARGE_HAS_PAY],
            ])
            ->sum("money");

        return intval(floatval($dbRes) * TaskEnum::TASK_RATIO);
    }

    // 获得用户某日充值金额
    public function getUserRechargeDailyMoney($userId, $date)
    {
        $dateStartTime = strtotime($date);
        $dateEndTime = strtotime($date . " +1 days") - 1;
        $dbRes = app("model_user_recharge")
            ->where([
                ["user_id", $userId],
                ["status", UserEnum::USER_RECHARGE_HAS_PAY],
                ["add_time", ">=", $dateStartTime],
                ["add_time", "<=", $dateEndTime],
            ])
            ->sum("money");

        return intval(floatval($dbRes) * TaskEnum::TASK_RATIO);
    }

    // 获取用户进入房间个数
    public function getUserEnterRoomNumber($userId)
    {
        $dbRes = app("model_room_stay_delay")
            ->where([
                ["is_deleted", 0],
                ["user_id", $userId],
            ])
            ->select([
                DB::raw("COUNT(DISTINCT room_id) as number"),
            ])
            ->first();

        $number = empty($dbRes) ? 0 : $dbRes['number'];

        return intval($number);
    }

    // 获取用户某日进入房间个数
    public function getUserEnterRoomDailyNumber($userId, $date)
    {
        $dateStartTime = strtotime($date);
        $dateEndTime = strtotime($date . " +1 days") - 1;

        $dbRes = app("model_room_stay_delay")
            ->where([
                ["is_deleted", 0],
                ["user_id", $userId],
                ["enter_time", ">=", $dateStartTime],
                ["enter_time", "<=", $dateEndTime],
            ])
            ->select([
                DB::raw("COUNT(DISTINCT room_id) as number"),
            ])
            ->first();

        $number = empty($dbRes) ? 0 : $dbRes['number'];

        return intval($number);
    }

    // 获取用户参与抢糖果次数
    public function getUserPlayCandyTimes($userId)
    {
        $dbRes = app("model_red_envelope_user_log")
            ->where([
                ["user_id", $userId],
            ])
            ->select([
                DB::raw("COUNT(DISTINCT room_log_id) as number"),
            ])
            ->first();

        $number = empty($dbRes) ? 0 : $dbRes['number'];

        return intval($number);
    }

    // 获取用户某日参与抢糖果次数
    public function getUserPlayCandyDailyTimes($userId, $date)
    {
        $dateStartTime = $date . " 00:00:00";
        $dateEndTime = $date . " 23:59:59";
        $dbRes = app("model_red_envelope_user_log")
            ->where([
                ["user_id", $userId],
                ["created_at", ">=", $dateStartTime],
                ["created_at", "<=", $dateEndTime],
            ])
            ->select([
                DB::raw("COUNT(DISTINCT room_log_id) as number"),
            ])
            ->first();

        $number = empty($dbRes) ? 0 : $dbRes['number'];

        return intval($number);
    }

    // 获取用户邀请好友次数
    public function getUserInviteTimes($userId)
    {
        $dbRes = app("model_user")
            ->where([
                ["parent_id", $userId],
            ])->count();

        return intval($dbRes);
    }

    // 获取用户某日邀请好友次数
    public function getUserInviteDailyTimes($userId, $date)
    {
        $dateStartTime = strtotime($date);
        $dateEndTime = strtotime($date . " +1 days") - 1;
        $dbRes = app("model_user")
            ->where([
                ["parent_id", $userId],
                ["register_time", ">=", $dateStartTime],
                ["register_time", "<=", $dateEndTime],
            ])->count();

        return intval($dbRes);
    }

    // 获取某日用户积分商城兑换次数
    public function getUserScoreMallExchangeDailyTimes($userId, $date)
    {
        $dateStartTime = strtotime($date);
        $dateEndTime = strtotime($date . " +1 days") - 1;
        $dbRes = app("model_score_mall_exchange")
            ->where([
                ["user_id", $userId],
                ["add_time", ">=", $dateStartTime],
                ["add_time", "<=", $dateEndTime],
            ])->count();

        return intval($dbRes);
    }

    // 用户今日是否已登录
    public function isTodayLogin($userId)
    {
        $redisKey = sprintf(UserEnum::USER_LOGIN_DATE, $userId);
        $date = date("Y-m-d");
        $redisRes = Redis::zscore($redisKey, $date);
        if (empty($redisRes)) {
            return false;
        }

        return true;
    }

    //获取用户信息
    public function getUserInfo($user_id)
    {
        $result = app('model_user_data')->withOnly('user', ['user_id', 'rank_id', 'nobility', 'money'])->select(
            ['user_id', 'nickname', 'head_picture', 'user_code', 'sex']
        )->where('user_id', $user_id)->first();
        if ($result) {
            return [
                'user_id' => $result->user->user_id,
                'rank_id' => $result->user->rank_id,
                'nobility_id' => $result->user->nobility,
                'nickname' => $result->nickname,
                'user_code' => $result->user_code,
                'head_picture' => $result->head_picture,
                'sex' => $result->sex,
                'money' => $result->user->money,
            ];
        }

        return [];
    }


    /**
     * 获取动态详情
     *
     * @param $blog_id
     *
     * @return mixed
     */
    public function getMicroBlogDetail($blog_id)
    {
        $blog = app('model_microblog')->where('id', $blog_id)->first();

        return $blog;
    }


    /**
     * 获取点赞详情
     *
     * @param $id
     * @param $type
     *
     * @return mixed
     */
    public function getLikeDetail($id, $type)
    {
        $like_detail = app('model_microblog_like')->where([
            'blog_id' => $id,
            'user_id' => UID,
            'type' => $type,
        ])->first();

        return $like_detail;
    }


    /**
     * 执行点赞操作
     *
     * @param $data
     *
     * @return bool
     * @throws BasicException
     */
    public function doLikeAction($data)
    {
        $res = app('model_microblog_like')->create($data);

        if ($res) {
            return true;
        }
        throw new BasicException(90026);
    }


    /**
     * 获取用户详情
     *
     * @param $uid
     *
     * @return mixed
     */
    public function getUserDetail($uid)
    {
        $user = app('model_user')->where('user_id', $uid)->first();

        return $user;
    }


    /**
     * 获取评论详情
     *
     * @param $id
     *
     * @return mixed
     */
    public function getCommentDetail($id)
    {
        $comment = app('model_microblog_comment')->where('id', $id)->first();

        return $comment;
    }

    /**
     * 编辑动态
     *
     * @param       $id
     * @param array $data
     *
     * @return bool
     * @throws BasicException
     */
    public function updateMicroBlog($id, $data = [])
    {
        $res = app('model_microblog')->where('id', $id)->update($data);

        return true;
        //        if($res) return true;
        //        throw new BasicException(90029);
    }


    /**
     * 获取评论或点赞列表
     *
     * @param     $param
     * @param     $page
     * @param int $perPage
     *
     * @return mixed
     */
    public function getBottomList($param, $page, $perPage = 15)
    {
        //type=1是评论列表2是点赞列表
        if ($param['type'] == 1) {
            $list = app('model_microblog_comment')->where(['blog_id' => $param['id'], 'status' => 1])
                ->withOnly('user_data', ['user_id', 'nickname', 'head_picture'])
                ->withOnly('u_data', ['user_id', 'nickname'])
                ->select('id', 'user_id', 'uid', 'content', 'add_time', 'like_num')
                ->orderBy('order', 'desc')->orderBy('add_time', 'desc')
                ->paginate($perPage, ['*'], '', $page);

            //查询自己点赞评论的ID数组
            $like_arr = app('model_microblog_like')->where([
                'user_id' => UID,
                'type' => 2,
            ])->pluck('blog_id')->toArray();

            foreach ($list as &$val) {
                $val->user_info = [
                    'user_id' => $val->user_id,
                    'nickname' => isset($val->user_data->nickname) ? $val->user_data->nickname : '',
                    'head_picture' => isset($val->user_data->head_picture) ? $val->user_data->head_picture : '',
                    //固定宽度为50
                ];
                $val->reply_info = [
                    'user_id' => $val->uid,
                    'nickname' => isset($val->u_data->nickname) ? $val->u_data->nickname : '',
                ];
                $val->add_time = date('m-d H:i', $val->add_time);
                $val->is_like = in_array($val->id, $like_arr) ? 1 : 0;
                unset($val->user_data);
                unset($val->u_data);
                unset($val->user_id);
                unset($val->uid);
            }
        } else {
            $list = app('model_microblog_like')->where(['blog_id' => $param['id'], 'type' => 1])
                ->withOnly('user_data', ['user_id', 'nickname', 'head_picture'])
                ->select('user_id')->orderBy('add_time', 'desc')->paginate($perPage,
                    ['*'], '', $page);

            foreach ($list as &$val) {
                $val->nickname = isset($val->user_data->nickname) ? $val->user_data->nickname : '';             //点赞用户昵称
                $val->head_picture = isset($val->user_data->head_picture) ? $val->user_data->head_picture : '';     //固定宽度为50
                unset($val->user_data);
            }
        }

        return $list;
    }


    /**
     * 获得发现页列表
     *
     * @param $param
     * @param $page
     * @param $perPage
     *
     * @return mixed
     */
    public function getMicroBlogIndexList($param, $page, $perPage)
    {
        //关注列表
        $follow_user = app('model_follow')->where('user_id', UID)->pluck('followed_user')->toArray();

        $uid = UID;

        $list = app('model_microblog')->where(['status' => 1])->where('verify', 3);

        if ($param['type'] == 1) {
            $list = $list->whereIn('privacy', [1, 2]);
            $list = $list->whereIn('user_id', $this->getFriendIds($follow_user));
        } elseif ($param['type'] == 2) {
            //推荐列表
            $list = $list->where(function ($query) use ($follow_user, $uid) {
                $query->where('privacy', 1)->orWhere(function ($query) use ($follow_user) {
                    $query->where('privacy', 2)->whereIn('user_id', $this->getFriendIds($follow_user));
                })->orWhere(function ($query) use ($uid) {
                    $query->where('privacy', 3)->where('user_id', $uid);
                });
            });
        } else {
            //推荐列表
            $list = $list->where(function ($query) use ($follow_user, $uid) {
                $query->where('privacy', 1)->orWhere(function ($query) use ($follow_user) {
                    $query->where('privacy', 2)->whereIn('user_id', $this->getFriendIds($follow_user));
                })->orWhere(function ($query) use ($uid) {
                    $query->where('privacy', 3)->where('user_id', $uid);
                });
            });
            //附近列表
            $geohash = new GeohashService();
            $local_hash = $geohash->encode($param['lat'], $param['lng']);
            $hash = substr($local_hash, 0, 3);
            $list = $list->where('geohash', 'like', "$hash%");
        }
        if (!empty($param['search'])) {
            $list = $list->where('content', 'like', "%{$param['search']}%");
        }

        $lat = $param['lat'];
        $lng = $param['lng'];
        $list = $list->withOnly('user_data',
            ['user_id', 'nickname', 'head_picture', 'sex', 'birthday'])->with([
            'user' => function ($query) {
                $query->select('user_id', 'rank_id', 'emchat_username', 'nobility')->withOnly('grade',
                    ['id', 'head_picture'])->withOnly('nobility_info', ['id', 'head_picture']);
            },
        ])
            ->select('id', 'user_id', 'content', 'img_arr', 'add_time', 'like_num', 'comment_num', 'position',
                'type', 'cover', 'position', 'extra', DB::raw("get_distance($lat,$lng,lat,lng) as distance"));

        if ($param['type'] == 3) {
            $list = $list->orderBy('distance', 'asc')->orderBy('add_time', 'desc')->paginate($perPage, ['*'], '',
                $page);
        } else {
            $list = $list->orderBy('add_time', 'desc')->paginate($perPage, ['*'], '', $page);
        }

        //查询自己点赞动态的ID数组
        $like_arr = app('model_microblog_like')->where(['user_id' => UID, 'type' => 1])->pluck('blog_id')->toArray();

        foreach ($list as &$val) {
            $val->add_time = (isset($val->add_time) && !empty($val->add_time)) ? format_time($val->add_time,
                true) : format_time(time(), true);
            $val->rank_pic = isset($val->user->grade->head_picture) ? $val->user->grade->head_picture : '';
            $val->nobility_pic = isset($val->user->nobility_info->head_picture) ? $val->user->nobility_info->head_picture : '';
            $val->emchat_username = isset($val->user->emchat_username) ? $val->user->emchat_username : '';
            $val->nickname = isset($val->user_data->nickname) ? $val->user_data->nickname : '';
            $val->head_picture = isset($val->user_data->head_picture) ? $val->user_data->head_picture : '';
            $val->sex = (isset($val->user_data->sex) && $val->user_data->sex == 1) ? $val->user_data->sex : 2;
            $val->age = isset($val->user_data->birthday) ? birthToAge($val->user_data->birthday, true) : 0;
            $val->is_like = in_array($val->id, $like_arr) ? 1 : 0;
            $val->is_concern = in_array($val->user_id, $follow_user) ? 1 : 0;
            $head_photo = RedisService::getHeadPicture($val->user_id);
            $val->head_photo = !empty($head_photo) ? $head_photo : '';
            if ($param['type'] == 1 || $param['type'] == 2 || empty($val->position)) {
                $val->distance = '';
            } else {
                $val->distance = $val->distance . 'km';
            }

            $val->special = app('model_user')->special($val->user_id);
            $val->extra = $val->extra ? json_decode($val->extra, true) : new \ArrayObject();
            unset($val->user);
            unset($val->user_data);
        }

        return $list;
    }

    //获取用户的所有好友（相互关注即是好友）
    //$followUserIds用户关注的用户id
    private function getFriendIds($followUserIds)
    {
        $friendIds = [];
        foreach ($followUserIds as $followUserId) {
            $exist = app('model_follow')->where('user_id', $followUserId)->where('followed_user', UID)->value('id');
            if ($exist) {
                $friendIds[] = $followUserId;
            }
        }
        array_push($friendIds, UID);

        return $friendIds;
    }

    /**
     * 过审的动态列表
     *
     * @param $param
     * @param $page
     * @param $perPage
     *
     * @return mixed
     */
    public function getMicroBlogIndexListNew($param, $page, $perPage)
    {
        $list = app('model_microblog')->where(['status' => 1]);
//      $list = $list->whereIn('id', [4526, 4525, 4515, 4514, 4513, 4511, 4509, 4508, 4504, 4503, 4502]);

        if (!empty($param['search'])) {
            $list = $list->where('content', 'like', "%{$param['search']}%");
        }

        $lat = $param['lat'];
        $lng = $param['lng'];
        $list = $list->withOnly('user_data',
            ['user_id', 'nickname', 'head_picture', 'sex', 'birthday'])->with([
            'user' => function ($query) {
                $query->select('user_id', 'rank_id', 'emchat_username', 'nobility')->withOnly('grade',
                    ['id', 'head_picture'])->withOnly('nobility_info', ['id', 'head_picture']);
            },
        ])
            ->select('id', 'user_id', 'content', 'img_arr', 'add_time', 'like_num', 'comment_num', 'position',
                'type', 'cover', 'position', DB::raw("get_distance($lat,$lng,lat,lng) as distance"));

        if ($param['type'] == 3) {
            $list = $list->orderBy('distance', 'asc')->orderBy('add_time', 'desc')->paginate($perPage, ['*'], '',
                $page);
        } else {
            $list = $list->orderBy('add_time', 'desc')->paginate($perPage, ['*'], '', $page);
        }

        //查询自己点赞动态的ID数组
        $like_arr = app('model_microblog_like')->where(['user_id' => UID, 'type' => 1])->pluck('blog_id')->toArray();

        //查询自己关注的列表
        $concern_arr = app('model_follow')->where('user_id', UID)->pluck('followed_user')->toArray();
        //        return $list;
        foreach ($list as &$val) {
            $val->add_time = (isset($val->add_time) && !empty($val->add_time)) ? format_time($val->add_time,
                true) : format_time(time(), true);
            $val->rank_pic = isset($val->user->grade->head_picture) ? $val->user->grade->head_picture : '';
            $val->nobility_pic = isset($val->user->nobility_info->head_picture) ? $val->user->nobility_info->head_picture : '';
            $val->emchat_username = isset($val->user->emchat_username) ? $val->user->emchat_username : '';
            $val->nickname = isset($val->user_data->nickname) ? $val->user_data->nickname : '';
            $val->head_picture = isset($val->user_data->head_picture) ? $val->user_data->head_picture : '';
            $val->sex = (isset($val->user_data->sex) && $val->user_data->sex == 1) ? $val->user_data->sex : 2;
            $val->age = isset($val->user_data->birthday) ? birthToAge($val->user_data->birthday, true) : 0;
            $val->is_like = in_array($val->id, $like_arr) ? 1 : 0;
            $val->is_concern = in_array($val->user_id, $concern_arr) ? 1 : 0;
            $head_photo = RedisService::getHeadPicture($val->user_id);
            $val->head_photo = !empty($head_photo) ? $head_photo : '';
            if (($param['type'] == 1) || empty($val->position)) {
                $val->distance = '';
            } else {
                $val->distance = $val->distance . 'km';
            }
            $val->special = app('model_user')->special($val->user_id);
            unset($val->user);
            unset($val->user_data);
        }

        return $list;
    }


    /**
     * 查询动态详情
     *
     * @param $id
     *
     * @return mixed
     * @throws BasicException
     */
    public function getBlogDetail($id, $param = [])
    {
        $lat = $param['lat'];
        $lng = $param['lng'];

        $detail = app('model_microblog')->where('id', $id)
            ->withOnly('user_data',
                ['user_id', 'nickname', 'head_picture', 'sex', 'birthday'])->with([
                'user' => function ($query) {
                    $query->select('user_id', 'rank_id', 'emchat_username', 'nobility')->withOnly('grade',
                        ['id', 'head_picture'])->withOnly('nobility_info', ['id', 'head_picture']);
                },
            ])->select('id', 'user_id', 'content', 'status', 'img_arr', 'add_time', 'like_num', 'comment_num',
                'position', 'type', 'cover', 'privacy', 'position', 'extra',
                DB::raw("get_distance($lat,$lng,lat,lng) as distance"))->first();

        if (empty($detail) || $detail->status == 2) {
            throw new BasicException(30062);
        }

        if ($detail->user_id != UID) {
            if ($detail->privacy == 3) {
                throw new BasicException(30063);
            }

            if ($detail->privacy == 2) {
                //查询好友关系
                $friend_one = app('model_friend')->where(['user_id' => $detail->user_id, 'friend_id' => UID])->first();

                $friend_two = app('model_friend')->where(['user_id' => UID, 'friend_id' => $detail->user_id])->first();

                if (empty($friend_one) && empty($friend_two)) {
                    throw new BasicException(30063);
                }
            }
        }

        //查询是否关注
        $concern = app('model_follow')->where(['user_id' => UID, 'followed_user' => $detail->user_id])->first();

        //查询是否点赞
        $like_detail = app('model_microblog_like')->where('blog_id', $detail->id)->where('user_id', UID)->where('type',
            1)->first();

        $detail->add_time = (isset($detail->add_time) && !empty($detail->add_time)) ? format_time($detail->add_time,
            true) : format_time(time(), true);
        $detail->rank_pic = isset($detail->user->grade->head_picture) ? $detail->user->grade->head_picture : '';
        $detail->emchat_username = isset($detail->user->emchat_username) ? $detail->user->emchat_username : '';
        $detail->nickname = isset($detail->user_data->nickname) ? $detail->user_data->nickname : '';
        $detail->head_picture = isset($detail->user_data->head_picture) ? $detail->user_data->head_picture : '';
        $detail->sex = (isset($detail->user_data->sex) && $detail->user_data->sex == 1) ? $detail->user_data->sex : 2;
        $detail->age = isset($detail->user_data->birthday) ? birthToAge($detail->user_data->birthday, true) : 0;
        $detail->nobility_pic = isset($detail->user->nobility_info->head_picture) ? $detail->user->nobility_info->head_picture : '';
        $detail->is_like = !empty($like_detail) ? 1 : 0;
        $detail->is_concern = !empty($concern) ? 1 : 0;
        $head_photo = RedisService::getHeadPicture($detail->user_id);
        $detail->head_photo = !empty($head_photo) ? $head_photo : '';
        if (($param['type'] == 1) || empty($detail->position) || empty($param['lat'])) {
            $detail->distance = '';
        } else {
            $detail->distance = $detail->distance . 'km';
        }
        $detail->extra = $detail->extra ? json_decode($detail->extra, true) : new \ArrayObject();
        unset($detail->user);
        unset($detail->user_data);

        return $detail;
    }


    /**
     * 新增动态消息
     *
     * @param array $data
     *
     * @return bool
     */
    public function createMicroMessage($data = [])
    {
        app('model_microblog_message')->create($data);

        return true;
    }

    /**
     * 动态消息列表
     *
     * @param     $param
     * @param int $page
     * @param int $perPage
     *
     * @return mixed
     */
    public function getMicroBlogMessage($param, $page = 1, $perPage = 15)
    {
        $list = app('model_microblog_message')->where(['user_id' => UID, 'type' => $param['type']]);

        if ($param['type'] == 1) {
            //type = 1是点赞消息
            $list = $list->withOnly('user_data',
                ['user_id', 'nickname', 'head_picture'])->with([
                'user' => function ($query) {
                    $query->select('user_id', 'rank_id')->withOnly('grade', ['id', 'head_picture']);
                },
            ])->withOnly('micro_blog', ['id', 'img_arr', 'cover', 'type'])->select('id', 'uid', 'blog_id',
                'add_time')->orderBy('add_time', 'desc')->paginate($perPage, ['*'], '', $page);

            foreach ($list as &$val) {
                $val->rank_pic = isset($val->user->grade->head_picture) ? $val->user->grade->head_picture : '';
                $val->nickname = isset($val->user_data->nickname) ? $val->user_data->nickname : '';
                $val->head_picture = isset($val->user_data->head_picture) ? $val->user_data->head_picture : '';
                $val->add_time = date('m-d H:i', $val->add_time);
                unset($val->user_data);
                unset($val->user);
                unset($val->blog_id);
            }
        } elseif ($param['type'] == 2) {
            //type = 2 是评论消息
            //            $list = $list
            $list = $list
                ->withOnly('user_data', ['user_id', 'nickname', 'head_picture'])
                ->with([
                    'user' => function ($query) {
                        $query->select('user_id', 'rank_id')->withOnly('grade', ['id', 'head_picture']);
                    },
                ])
                ->withOnly('micro_blog', ['id', 'img_arr', 'cover', 'type'])
                ->withOnly('reply_user', ['user_id', 'nickname'])
                ->withOnly('comment', ['id', 'content'])
                ->select('id', 'uid', 'blog_id', 'add_time', 'reply_uid', 'content_id')->orderBy('add_time',
                    'desc')->paginate($perPage, ['*'], '', $page);

            //            return $list;
            foreach ($list as &$val) {
                $val->rank_pic = isset($val->user->grade->head_picture) ? $val->user->grade->head_picture : '';
                $val->nickname = isset($val->user_data->nickname) ? $val->user_data->nickname : '';
                $val->head_picture = isset($val->user_data->head_picture) ? $val->user_data->head_picture : '';
                $val->comment_content = isset($val->comment->content) ? $val->comment->content : '';
                $val->reply_nickname = isset($val->reply_user->nickname) ? $val->reply_user->nickname : '';
                $val->add_time = date('m-d H:i', $val->add_time);
                unset($val->reply_user);
                unset($val->comment);
                unset($val->user_data);
                unset($val->user);
                unset($val->blog_id);
                unset($val->content_id);
                unset($val->reply_uid);
            }
        } else {
            //type = 3 是关注消息
            $list = $list->withOnly('user_data', ['user_id', 'nickname', 'head_picture'])->select('id', 'uid',
                'add_time')->orderBy('add_time', 'desc')->paginate($perPage, ['*'], '', $page);

            //查询自己关注的列表
            $concern_arr = app('model_follow')->where('user_id', UID)->pluck('followed_user')->toArray();

            foreach ($list as &$val) {
                $val->nickname = isset($val->user_data->nickname) ? $val->user_data->nickname : '';
                $val->head_picture = isset($val->user_data->head_picture) ? $val->user_data->head_picture : '';
                $val->is_concern = in_array($val->uid, $concern_arr) ? 1 : 0;
                unset($val->user_data);
            }
        }

        return $list;
    }


    // 是否关注
    public function isFollow($userId, $targetUserId)
    {
        $concern = false;
        $user_concern = app('model_follow')->where(['user_id' => $userId, 'followed_user' => $targetUserId])->first();

        if (!empty($user_concern)) {
            $concern = true;
        }

        return $concern;
    }

    /**
     * 检测两人是否是好友
     *
     * @param $userId
     * @param $friendId
     *
     * @return bool
     */
    public static function checkIsFriend($userId, $friendId): bool
    {
        return Friend::query()->where(['user_id' => $userId, 'friend_id' => $friendId])->exists();
    }

    // 获得外部任务卡数据
    public function getOutUserCardData($userId, $curUserId)
    {
        $whereArr = [
            ["t1.user_id", "=", $userId],
        ];

        $userModel = app('model_user');
        $userDataModel = app('model_user_data');
        $gradeConfigModel = app('model_grade_config');
        $nobilityConfigModel = app('model_nobility');
        $regionModel = app("model_region");
        $roomJoinModel = app("model_room_join");

        $res = $userModel
            ->from($userModel->getTable() . " as t1")
            ->select([
                "t1.user_id",
                "t2.nickname",
                "t2.user_code",
                "t2.head_picture",
                "t2.signature",
                "t2.intro_voice",
                "t2.intro_voice_time",
                "t2.sex",
                "t2.city_id",
                "t2.birthday",
                DB::raw("t5.region_name as city_name"),
                "t1.emchat_username",
                "t2.constellation",
                DB::raw("t6.room_id as track_room_id"),
                DB::raw("t6.on_line as is_online"),
                "t1.rank_id",
                "t1.nobility",
                DB::raw("t3.grade as rank_name"),
                DB::raw("t3.head_picture as rank_picture"),
                DB::raw("t4.name as nobility_name"),
                DB::raw("t4.head_picture as nobility_picture"),
            ])
            ->leftJoin(DB::raw($userDataModel->getTable() . " as t2"), "t1.user_id", "=", "t2.user_id")
            ->leftJoin(DB::raw($gradeConfigModel->getTable() . " as t3"), "t1.rank_id", "=", "t3.id")
            ->leftJoin(DB::raw($nobilityConfigModel->getTable() . " as t4"), "t1.nobility", "=", "t4.id")
            ->leftJoin(DB::raw($regionModel->getTable() . " as t5"), "t2.city_id", "=", "t5.id")
            ->leftJoin(DB::raw($roomJoinModel->getTable() . " as t6"), "t1.user_id", "=", "t6.user_id")
            ->where($whereArr)->orderBy("t6.on_line", "desc")->first();

        if (empty($res)) {
            throw new BasicException(10014);
        }

        if (empty($res['track_room_id'])) {
            $trackRoomId = 0;
        } else {
            $trackRoomId = empty($res['is_online']) ? 0 : $res['track_room_id'];
        }
        if ($trackRoomId) {
            $roomType = RoomEnum::clientRoomType(RedisService::getRoomDetailByRoomId($trackRoomId, 'sys_type_id'));
        } else {
            $roomType = 0;
        }
        $intimacyData = app('repo_connection')->getIntimacyData($curUserId, $userId) ?: [];

        $isCp = empty($intimacyData['is_cp']) ? 0 : intval($intimacyData['is_cp']);
        $currentIntimacyLevel = empty($intimacyData['current_intimacy_level']) ? "" : $intimacyData['current_intimacy_level'];
        $intimacyPicture = empty($intimacyData['intimacy_picture']) ? "" : $intimacyData['intimacy_picture'];
        $intimacyString = empty($intimacyData['intimacy_string']) ? "" : $intimacyData['intimacy_string'];
        $todayIntimacyString = empty($intimacyData['today_intimacy_string']) ? "" : $intimacyData['today_intimacy_string'];

        //公会铭牌
        $sociatyBadge = MapService::userSociatyBadge($userId);
        $sociatyBadgeName = $sociatyBadge['name'] ?? "";
        $sociatyBadgeImg = $sociatyBadge['img'] ?? "";

        return [
            "user_id" => $res['user_id'] ?? "",
            "user_code" => $res['user_code'] ?? "",
            "nickname" => $res['nickname'] ?? "",
            "head_picture" => $res['head_picture'] ?? "",
            "intro" => $res['signature'] ?? "",
            "intro_voice" => $res['intro_voice'] ?? "",
            "intro_voice_time" => $res['intro_voice_time'] ?? 0,
            "sex" => $res['sex'] ?: 0,
            "age" => !isset($res['birthday']) ? 0 : birthToAge($res['birthday'], true),
            "city" => $res['city_name'] ?? "",
            "constellation" => $res['constellation'] ?? "",
            "track_room_id" => $trackRoomId,
            "room_type" => $roomType,
            "has_follow" => intval($this->isFollow($curUserId, $userId)),
            "em_chat_username" => $res['emchat_username'] ?? "",
            "rank_info" => [
                "rank_id" => $res['rank_id'] ?? "",
                "rank_name" => $res['rank_name'] ?? "",
                "nobility_id" => $res['nobility'] ?? "",
                "nobility_name" => $res['nobility_name'] ?? "",
                "nobility_picture" => $res['nobility_picture'] ?? "",
                "head_frame_picture" => app('model_mall_orders')->getHeadPicture($userId),
                "rank_picture" => $res['rank_picture'] ?? "",
            ],
            "intimacy_info" => [
                "is_cp" => $isCp,
                "current_intimacy_level" => $currentIntimacyLevel,
                "intimacy_picture" => $intimacyPicture,
                "intimacy_string" => $intimacyString,
                "today_intimacy_string" => $todayIntimacyString,
            ],
            "sociaty_badge" => [
                "name" => $sociatyBadgeName,
                "img" => $sociatyBadgeImg,
            ],
            'special' => app('model_user')->special($userId),
        ];
    }

    //获取粉丝列表
    public function getFansList($user_id, $perPage = 20, $onlineStatus = '')
    {
        $query = app('model_follow')::query()
            ->join('ln_user_data', 'ln_follow.user_id', '=', 'ln_user_data.user_id')
            ->join('ln_user', 'ln_follow.user_id', '=', 'ln_user.user_id')
            ->where('ln_follow.followed_user', $user_id);
        if ($onlineStatus === 'online') {
            $query->where('ln_user.offline_time', 0);
        }
        $result = $query->orderBy('ln_follow.add_time', 'desc')->paginate($perPage);
        //粉丝列表删除
        $followList = app('model_follow')->select('followed_user')->where(['user_id' => $user_id]);
        $followIds = $followList->pluck('followed_user')->toArray();

        $friendIds = $result->pluck('user_id')->toArray();
        $remarks = UserLinkman::query()->where('user_id', UID)->whereIn('link_user_id', $friendIds)->get()->keyBy('link_user_id')->toArray();

        $result->getCollection()->transform(function ($item) use ($followIds, $remarks) {
            return collect([
                'is_follow' => in_array($item->user_id, $followIds) ? true : false,
                'user_id' => $item->user_id,
                'offline_time' => $item->offline_time,
                'user_code' => $item->user_code ?? '',
                'mood' => $item->mood ?? 1,
                'nickname' => $item->nickname ?? '',
                'head_picture' => $item->head_picture ?? '',
                'signature' => $item->signature ?? '',
                'age' => birthToAge($item->birthday ?? 0, true),
                'sex' => $item->sex ?? 0,
                'emchat_username' => $item->emchat_username ?? '',
                'nobility_icon' => app('model_nobility')->getNobilityIcon($item->nobility ?? 0),
                'level_icon' => app('model_grade_config')->getGradeIcon($item->rank_id ?? 0),
                'charm_icon' => app('model_charm_config')->getCharmIcon($item->charm_id ?? 0),
                'rank_info' => app('model_user')->rankInfo($item->user_id),
                'remarks' => $remarks[$item->user_id] ? $remarks[$item->user_id]['remarks'] : '',
                'bg_picture' => $remarks[$item->user_id] ? $remarks[$item->user_id]['bg_picture'] : '',
                'recharge_icon' => RedisService::getUserRechargeIcon($item->user_id),
            ]);
        });
        return $result;
    }

    //用户关注列表
    public function getFollowList($user_id, $perPage = 20, $onlineStatus = '')
    {
        $query = app('model_follow')
            ->join('ln_user_data', 'ln_follow.followed_user', '=', 'ln_user_data.user_id')
            ->join('ln_user', 'ln_follow.followed_user', '=', 'ln_user.user_id')
            ->where('ln_follow.user_id', $user_id);
        if ($onlineStatus === 'online') {
            $query->where('ln_user.offline_time', 0);
        }
        $result = $query->orderBy('ln_follow.add_time', 'desc')->paginate($perPage);

        $friendIds = $result->pluck('followed_user')->toArray();
        $remarks = UserLinkman::query()->where('user_id', UID)->whereIn('link_user_id', $friendIds)->get()->keyBy('link_user_id')->toArray();

        $result->getCollection()->transform(function ($item) use ($remarks) {
            return collect([
                'followed_user' => $item->followed_user,
                'offline_time' => $item->offline_time,
                'user_code' => $item->user_code ?? '',
                'mood' => $item->mood ?? 1,
                'nickname' => $item->nickname ?? '',
                'head_picture' => $item->head_picture ?? '',
                'signature' => $item->signature ?? '',
                'age' => birthToAge($item->birthday ?? 0, true),
                'sex' => $item->sex ?? 0,
                'emchat_username' => $item->emchat_username ?? '',
                'nobility_icon' => app('model_nobility')->getNobilityIcon($item->nobility ?? 0),
                'level_icon' => app('model_grade_config')->getGradeIcon($item->rank_id ?? 0),
                'charm_icon' => app('model_charm_config')->getCharmIcon($item->charm_id ?? 0),
                'rank_info' => app('model_user')->rankInfo($item->followed_user),
                'remarks' => $remarks[$item->followed_user] ? $remarks[$item->followed_user]['remarks'] : '',
                'bg_picture' => $remarks[$item->followed_user] ? $remarks[$item->followed_user]['bg_picture'] : '',
                'recharge_icon' => RedisService::getUserRechargeIcon($item->followed_user),
            ]);
        });

        return $result;
    }

    public function getFriendList($user_id, $perPage = 20, $groupId = 0, $onlineStatus = "")
    {
        $where['user_id'] = $user_id;
//        $result = app('model_friend')->with([
//            'friend_user:user_id,emchat_username,nobility,rank_id',
//            'friend_user_data:user_id,head_picture,nickname,signature,birthday,sex,user_code',
//        ])->where($where)->orderBy('add_time', 'desc')->paginate($perPage);

        $result = app('model_friend')->getFriendList($user_id, $onlineStatus, $perPage);

        $groupMembers = Collection::make([]);
        if (!empty($groupId)) {
            $groupMembers = GroupMemberRepository::getInstance()->get(["group_id" => $groupId]);
        }

        $friendIds = $result->pluck('friend_id')->toArray();
        $remarks = UserLinkman::query()->where('user_id', UID)->whereIn('link_user_id', $friendIds)->get()->keyBy('link_user_id')->toArray();

        $result->getCollection()->transform(function ($item) use ($groupMembers, $remarks) {
            $groupMember = $groupMembers->where("user_id", $item->user_id)->first();
            return collect([
                'offline_time' => $item->offline_time,
                'friend_id' => $item->friend_id,
                'user_code' => $item->user_code ?? '',
                'nickname' => $item->nickname ?? '',
                'head_picture' => $item->head_picture ?? '',
                'signature' => $item->signature ?? '',
                'birthday' => $item->birthday ?? '',
                'sex' => $item->sex ?? 0,
                'emchat_username' => $item->emchat_username ?? '',
                'nobility' => $item->nobility ?? 0,
                'rank_id' => $item->rank_id ?? 0,
                'age' => birthToAge($item->birthday ?? 0, true),
                'rank_info' => app('model_user')->rankInfo($item->friend_id),
                'nobility_icon' => app('model_nobility')->getNobilityIcon($item->nobility ?? 0),
                "group_role" => (!$groupMember) ? null : $groupMember->role,
                'level_icon' => app('model_grade_config')->getGradeIcon($item->rank_id ?? 0),
                'charm_icon' => app('model_charm_config')->getCharmIcon($item->charm_id ?? 0),
                'remarks' => $remarks[$item->friend_id] ? $remarks[$item->friend_id]['remarks'] : '',
                'bg_picture' => $remarks[$item->friend_id] ? $remarks[$item->friend_id]['bg_picture'] : '',
                'recharge_icon' => RedisService::getUserRechargeIcon($item->friend_id),
            ]);
        });

        return $result;
    }

    //原始数据获取用户ids
    private function getUserIdsByDbObj($obj)
    {
        $data = $obj->toArray();
        $ids = [];
        foreach ($data['data'] as $k => $v) {
            if (isset($v['user_id'])) {
                $ids[] = $v['user_id'];
            }
        }
        $this->uniqueIds = array_unique($ids);

        return $this->uniqueIds;
    }

    //通过id获取用户个人主页信息
    public function homepage($user_id)
    {
        $oldUserId = $user_id;
        $where['user_id'] = $user_id;
        $field = ['user_id', 'emchat_username', 'rank_id', 'charm_id', 'nobility as nobility_id', 'offline_time'];
        $result = app('model_user')->select($field)->where($where)->with('user_data:user_id,user_code,head_picture,nickname,sex,user_photo,signature,birthday,constellation,profession,city_id,intro_voice,intro_voice_time,vedio,vedio_cover,streamer_level')->first();
        if (!$result) {
            throw new BasicException(10014);
        }
        $result = $result->toArray();
        $user = array_merge($result['user_data'], $result);
        unset($user['user_data']);
        $user['intro_voice'] = $user['intro_voice'] ?: '';
        $user['vedio_cover'] = $user['vedio_cover'] ?: '';
        $user['vedio'] = $user['vedio'] ?: '';
        $user['sociaty_name']  = RedisService::setGuildUser($user_id) ?: '';
        $user['nobility_icon'] = app('model_nobility')->getNobilityIcon($user['nobility_id']);
        $user['nobility_image'] = app('model_nobility')->getNobilityImage($user['nobility_id']);
        $user['level_icon'] = app('model_grade_config')->getGradeIcon($user['rank_id']);
        $user['charm_icon'] = app('model_charm_config')->getCharmIcon($user['charm_id']);
        $user_id = $user['user_id'];

        $info = app('model_follow')->getUserFollow(UID, $user_id);
        $user['follow'] = $info ? 1 : 0;
        //关注数量
        $user['follow_count'] = app("repo_user")->getUserFollowNumber($user_id);
        //粉丝数量
        $user['fans_count'] = app("repo_user")->getUserFansNumber($user_id);
        $user['friend_count'] = app("repo_user")->getUserFriendNumber($user_id);

        $unlockCardIds = GroupFriendCardRepository::getInstance()->getunlockIds($user_id);
        $user['unlock_cards'] = $unlockCardIds ? json_encode($unlockCardIds) : '';

        $total = 6;
        if ($user['vedio']) {
            $total--;
        }
        if ($user['head_picture']) {
            $total--;
        }
        $user_images = app('model_user_photo')->getPhoto($user_id, $total);

        $user['user_photo'] = [
            'vedio' => $user['vedio'],
            'vedio_cover' => $user['vedio_cover'],
            'avatar' => $user['head_picture'],
            'list' => $user_images,
        ];

        $user['age'] = birthToAge($user['birthday'], true);
        if ($user['birthday'] == '0000-00-00') {
            $user['birthday'] = '';
        }
        $user['city'] = '';
        if ($user['city_id'] > 0) {
            $user['city'] = app('model_region')->getRegionNameById($user['city_id']);
        }
        unset($user['city_id']);

        if ($user['offline_time'] <= 0) {
            $user['is_online'] = 1;
        } elseif ((NOW_TIME - $user['offline_time']) > 300) {
            $user['is_online'] = 0;
        } else {
            $user['is_online'] = 1;
        }
        unset($user['offline_time']);

        //获取用户是否设置了访问隐身
        if ($user_id != UID) {
            $result = app('model_user_config')->getUserInform(UID);
            if (!$result || $result['visit'] == 2) {
                //记录访问历史
                app('model_user_visit')->addVisitData($user_id, UID);
            }
        }

        $user['only_friend'] = 2;
        $user['is_private_chat'] = 2;

        //判断用户编号是否是靓号
        $user['good_number'] = checkGoodNumber($user['user_code']);

        //用户当前所在房间信息
        $user['room_id_current'] = RedisService::getUserInRoom($oldUserId);
        if (!empty($user['room_id_current'])) {
            $roomDetail = RedisService::getRoomDetailByRoomId($user['room_id_current']);
            $user['room_type'] = RoomEnum::clientRoomType($roomDetail['sys_type_id'] ?? 0);
            $user['room_name_current'] = $roomDetail['room_name'] ?? '';
            $user['room_cover_picture'] = $roomDetail['cover_picture'] ?? '';
        } else {
            $user['room_type'] = 0;
            $user['room_name_current'] = '';
            $user['room_cover_picture'] = '';
        }

        //用户自己的房间
        $user_room = app('model_user_room')->getUserRoom($user_id);
        $user['room_id_owner'] = $user_room->id ?? 0;
        $user['room_name_owner'] = $user_room->room_name ?? '';

        //我正在使用的头像框
        $user['picture'] = app('model_mall_orders')->getHeadPicture($user_id);

        // 特效
        $user['special'] = app('model_user')->special($user_id);

        //公会铭牌
        $sociatyBadge = MapService::userSociatyBadge($user_id);
        $user['sociaty_badge'] = [
            "name" => $sociatyBadge['name'] ?? "",
            "img" => $sociatyBadge['img'] ?? "",
        ];
        //我是否拉黑了对方
        $user['is_black'] = app('model_black_list')->checkUserBlack(UID, $user_id);

        //用户主播等级图标
        $user['streamer_level_icon'] = StreamerLevel::query()->where(['level' => $user['streamer_level']])->value('icon') ?? '';


        //获取用户审核状态
        $verifyRes = $this->returnUserVerifyStatus($user_id);
        if ($user_id == UID) {
            $user = array_merge($user, $verifyRes);
        } else {
            $user = array_merge($verifyRes, $user);
        }
        //用户5个行为的封禁状态
        $user_actions = $this->getUserActionAuth($user_id);
        $actions = [
            ContentNameEnum::NICKNAME => 'nickname',
            ContentNameEnum::HEAD_PICTURE => 'head_picture',
            ContentNameEnum::VIDEO_INTRO => 'vedio',
            ContentNameEnum::VOICE_INTRO => 'voice',
            ContentNameEnum::SIGNATURE => 'signature',
            ContentNameEnum::ALBUM => 'album',
        ];
        $forbid = [];
        foreach ($actions as $k => $v) {
            $user[$v . '_forbid_time'] = 0;
            if (isset($user_actions[$k]) && ($user_actions[$k] == -1 || $user_actions[$k] > time())) {
                //                $expire_time = HelperService::time_format($user_actions[$k] - time());
                $expire_time = $user_actions[$k] == -1 ? -1 : ($user_actions[$k] - time() < 0 ? 0 : $user_actions[$k] - time());
                $user[$v . '_forbid_time'] = $expire_time;
                $forbid['verify_' . $v] = 3;
            }
        }

        $user['user_is_new'] = 0;

        $user['is_accompany'] = 0; // 陪玩认证
        $user['accompany_label'] = '';
        $ability = AccompanyUser::query()->where('user_id', $user_id)->where('status', 1)
            ->first();
        if (!empty($ability) && ($ability['ban_time'] == null || $ability['ban_time'] < time())) {
            $user['is_accompany'] = 1;
            $user['accompany_label'] = 'https://moka-test-hangzhou.oss-cn-hangzhou.aliyuncs.com/image/79a89e4d0207ddcc6d31d168170d71cb131ab7f7.png';
        }

        if (time() - $user['register_time'] < RoomEnum::USER_NEW_TIME) {
            $user['user_is_new'] = 1;
        }
        /*$recharge = UserRecharge::query()->where('user_id', $user_id)->where('status', 2)->first();
        if (time() - $recharge['pay_time'] < RoomEnum::USER_NEW_TIME) {
            $user['user_is_new'] = 2;
        }*/
        $user = array_merge($user, $forbid);

        $user['title_gift_info'] = $this->getUserTitleNowInfo($user_id);
        $user['recharge_icon'] = RedisService::getUserRechargeIcon($user_id);

        return $user;
    }

    //我的信息
    public function myInfo($user_id)
    {
        $result = app('model_user')->from('ln_user as a')
            ->join('ln_user_data as b', 'a.user_id', '=', 'b.user_id')
            ->leftJoin('ln_user_room as c', 'a.user_id', '=', 'c.user_id')
            ->where(['a.user_id' => $user_id])->get([
                'a.money', 'a.user_id', 'b.user_code', 'b.head_picture', 'b.nickname', 'b.sex', 'a.role', 'a.register_time',
                'b.birthday', 'c.id as room_id', 'a.nobility', 'a.rank_id', 'a.charm_id', 'b.constellation',
                'c.sys_type_id', 'b.streamer_level', 'b.intro_voice', 'b.intro_voice_time', 'b.signature'
            ])->first();

        if (!$result) {
            throw new BasicException(10014);
        }
        $user = $result->toArray();
        //自己拥有的房间
        $user['room_id'] = $user['room_id'] ?? 0;
        unset($user['user_room']);
        $user['room_type'] = RoomEnum::clientRoomType($user['sys_type_id']);

        //当前所在房间
        $user['room_id_current'] = RedisService::getUserInRoom($user_id);
        if (!empty($user['room_id_current'])) {
            $user['room_type_current'] = RoomEnum::clientRoomType(RedisService::getRoomDetailByRoomId($user['room_id_current'], 'sys_type_id'));
        } else {
            $user['room_type_current'] = 0;
        }

        $user['nobility_icon'] = app('model_nobility')->getNobilityIcon($user['nobility']);
        $user['level_icon'] = app('model_grade_config')->getGradeIcon($user['rank_id']);
        $user['charm_icon'] = app('model_charm_config')->getCharmIcon($user['charm_id']);
        //好友数量
//        $user['friend_count'] = $this->getUserFriendNumber($user_id);
        $user['friend_count'] = app('model_friend')->getUserFriendCount($user_id);
        //关注数量
        $user['follow_count'] = $this->getUserFollowNumber($user_id);
//        $user['follow_count'] = app('model_follow')->getUserFollowCount($user_id);
        $user['favorite_count'] = app('model_room_favorite')->getUserFavoriteCount($user_id);
        //粉丝数量
//        $user['fans_count'] = $this->getUserFansNumber($user_id);
        $user['fans_count'] = app('model_follow')->getUserFansCount($user_id);
        //最近来访数量
        $userVisitorData = app('model_user_visit')->getUserVisitAllCount($user_id);
        $user['visit_count'] = $userVisitorData['recent_count'] ?? 0;
        $user['visit_all_count'] = ($userVisitorData['recent_count'] + $userVisitorData['history_count']) ?? 0;
        // 群数量
        $user["group_count"] = GroupMemberRepository::getInstance()->userGroupCount($user_id);

        $user['role'] = $user['role'] == 2 ? 5 : 1;
        $user['user_is_new'] = app('model_user')->checkUserNew($user_id);
        unset($user['register_time']);

        $user['age'] = birthToAge($user['birthday'], true);
        if ($user['age'] > 120) {
            $user['age'] = 0;
        }
        unset($user['birthday']);

        //vip名称
        $user['rank_info'] = app('model_user')->rankInfo($user_id);

        //是否通过了资质头像审核
        $user['skill_avatar'] = app('redis')->get('u:avatar:skill:' . $user_id) ? 0 : 1;

        $user['good_number'] = checkGoodNumber($user['user_code']);

        $user['auth_status'] = app('repo_user_auth')->checkUserAuth($user_id);

        $user['special'] = app('model_user')->special($user_id);

        $sociaty_jump_new = app('model_config')->getValue('SOCIATY_JUMP_NEW');
        $sociaty_jump_new = $sociaty_jump_new == 1 ? 1 : 0;
        $user['sociaty_jump_new'] = $sociaty_jump_new;

        //用户主播等级图标
        $user['streamer_level_icon'] = StreamerLevel::query()->where(['level' => $user['streamer_level']])->value('icon') ?? '';


        //获取用户审核状态
        $verifyRes = $this->returnUserVerifyStatus($user_id);
        $user = array_merge($user, $verifyRes);
        //用户5个行为的封禁状态
        $user_actions = $this->getUserActionAuth($user_id);
        $actions = [
            ContentNameEnum::NICKNAME => 'nickname',
            ContentNameEnum::HEAD_PICTURE => 'head_picture',
            ContentNameEnum::VIDEO_INTRO => 'vedio',
            ContentNameEnum::VOICE_INTRO => 'voice',
            ContentNameEnum::SIGNATURE => 'signature',
            ContentNameEnum::ALBUM => 'album',
        ];
        $forbid = [];
        foreach ($actions as $k => $v) {
            $user[$v . '_forbid_time'] = 0;
            if (isset($user_actions[$k]) && ($user_actions[$k] == -1 || $user_actions[$k] > time())) {
                //                $expire_time = HelperService::time_format($user_actions[$k] - time());
                $expire_time = $user_actions[$k] == -1 ? -1 : ($user_actions[$k] - time() < 0 ? 0 : $user_actions[$k] - time());
                $user[$v . '_forbid_time'] = $expire_time;
                $forbid['verify_' . $v] = 3;
            }
        }
        $user = array_merge($user, $forbid);

        $user['title_gift_info'] = $this->getUserTitleNowInfo($user_id);
        $user['recharge_icon'] = RedisService::getUserRechargeIcon($user_id);

        return $user;
    }

    //除了照片墙的其余5个类型的变更
    public function returnUserVerifyStatus($user_id)
    {
        $verifyInfo = $this->getUserVerifyStatus($user_id);
        $user = [
            ContentNameEnum::NICKNAME => [
                'key' => 'verify_nickname',
                'relative_key' => 'nickname',
                'status' => 2,
                'value' => '',
            ],
            ContentNameEnum::HEAD_PICTURE => [
                'key' => 'verify_head_picture',
                'relative_key' => 'head_picture',
                'status' => 2,
                'value' => '',
            ],
            ContentNameEnum::VIDEO_INTRO => [
                'key' => 'verify_vedio',
                'relative_key' => 'vedio',
                'status' => 2,
                'value' => '',
            ],
            ContentNameEnum::VOICE_INTRO => [
                'key' => 'verify_voice',
                'relative_key' => 'intro_voice',
                'status' => 2,
                'value' => '',
            ],
            ContentNameEnum::SIGNATURE => [
                'key' => 'verify_signature',
                'relative_key' => 'signature',
                'status' => 2,
                'value' => '',
            ],
        ];
        foreach ($user as $k => $v) {
            if (isset($verifyInfo[$k]) && $verifyInfo[$k]['status'] == 1) {    //仅获取审核中的记录,对审核拒绝的记录根据封禁状态进行处理,且审核拒绝的记录已经对主表数据进行还原,直接取主表数据没有问题
                $user[$k]['status'] = $verifyInfo[$k]['status'];
                $other_data = empty($verifyInfo[$k]['other_data']) ? [] : $verifyInfo[$k]['other_data'];
                $other_data = is_array($other_data) ? $other_data : json_decode($other_data, true);
                $user[$k]['value'] = [
                    'url' => !isset($verifyInfo[$k]['url']) ? '' : $verifyInfo[$k]['url'],
                    'other_data' => $other_data,
                ];
            }
        }
        $reUser = [];
        foreach ($user as $k => $v) {
            $reUser[$v['key']] = $v['status'];
            if ($v['status'] == 1) {
                $reUser[$v['relative_key']] = $v['value'];
            }
        }

        if (isset($reUser['nickname'])) {
            $reUser['nickname'] = $reUser['nickname']['url'];
        }
        if (isset($reUser['head_picture'])) {
            $reUser['head_picture'] = $reUser['head_picture']['url'];
        }
        if (isset($reUser['intro_voice'])) {
            $reUser['intro_voice_time'] = isset($reUser['intro_voice']['other_data']['intro_voice_time']) ? $reUser['intro_voice']['other_data']['intro_voice_time'] : 0;
            $reUser['intro_voice'] = $reUser['intro_voice']['url'];
        }
        if (isset($reUser['vedio'])) {
            $reUser['vedio_cover'] = isset($reUser['vedio']['other_data']['vedio_cover']) ? $reUser['vedio']['other_data']['vedio_cover'] : '';
            $reUser['vedio'] = $reUser['vedio']['url'];
        }
        if (isset($reUser['signature'])) {
            $reUser['signature'] = $reUser['signature']['url'];
        }

        return $reUser;
    }

    //用户照片墙
    public function photoWall($user_id, $page_size = 20)
    {
        $user = app('model_user_data')->select(['vedio', 'vedio_cover', 'head_picture as avatar'])->where('user_id', $user_id)->first();
        $user_info['vedio'] = $user['vedio'] ?? '';
        $user_info['vedio_cover'] = $user['vedio_cover'] ?? '';
        $user_info['avatar'] = $user['avatar'] ?? '';
        $user_images = app('model_user_photo')->select(['id', 'url', 'state'])->where('user_id', $user_id)->whereIn('state', [0, 1])->paginate($page_size);

        return ['user_info' => $user_info, 'user_image' => $user_images];
    }

    //编辑用户资料
    public function editUserData($user_id, $params = [])
    {
        //是否存在用户
        $where['user_id'] = $user_id;
        $info = app('model_user_data')->where($where)->first();

        $user_no = $params['user_no'] ?? ''; //邀请码
        if ($user_no) {
            if (!is_numeric($user_no)) {
                throw new BasicException(21000);
            }
        }

        if (isset($params['sex'])) {
            $sex = $params['sex']; //1.男 2.女
            if (!in_array($sex, [1, 2])) {
                throw new BasicException(21001);
            }
            //性别一经确认不可修改
            $change_count = app('model_user_change')->getChangeCount($user_id, 3);
            $sex_config = app('model_config')->getValue('CHANGE_SEX_COUNT');
            if ($sex_config > 0 && $change_count > $sex_config) {
                throw new BasicException(21002);
            }
            $data['sex'] = $sex;
        }
        $intro_voice = $params['intro_voice'] ?? ''; //语音简介
        if ($intro_voice) {
            $this->checkUserAction($user_id, ContentNameEnum::VOICE_INTRO);
            if ($intro_voice == 'delete') {
                $data['intro_voice'] = '';
                $data['intro_voice_time'] = 0;
                //同时在变更表删除
                $w = [
                    'user_id' => $user_id,
                    'content_name' => ContentNameEnum::VOICE_INTRO,
                ];
                app('model_user_change_action')->where($w)->update(['status' => 0, 'del_time' => time()]);
                $this->deleteUserVerifyStatus($user_id, ContentNameEnum::VOICE_INTRO);
            } else {
                $intro_voice_time = $params['intro_voice_time'] ?? 0; //语音简介时长
                if ($intro_voice_time > 60 || $intro_voice_time < 15) {
                    throw new BasicException(21003);
                }

                $data['intro_voice'] = $intro_voice;
                $data['intro_voice_time'] = $intro_voice_time;

                //保存用户变更记录
                $id = app('model_user_change_action')->insertGetId([
                    'user_id' => $user_id,
                    'url' => $intro_voice,
                    'other_data' => json_encode([
                        'intro_voice_time' => $intro_voice_time,
                    ]),
                    'content_name' => ContentNameEnum::VOICE_INTRO,
                    'add_time' => time(),
                ]);
                $this->setUserVerifyStatus($user_id, ContentNameEnum::VOICE_INTRO, [
                    'max_id' => $id,
                    'status' => 1,
                    'url' => $intro_voice,
                    'other_data' => json_encode([
                        'intro_voice_time' => $intro_voice_time,
                    ]),
                ]);

                $jobData = [
                    'user_id' => $user_id,
                    'key_id' => $id,
                    'content_type' => ContentTypeEnum::AUDIO,
                    'content_name' => ContentNameEnum::VOICE_INTRO,
                    'content' => '',
                    'content_origin' => $info->intro_voice . '|' . $info->intro_voice_time,
                    'voices' => json_encode([$intro_voice]),
                ];
                $contentQueueName = env('CONTENT_QUEUE_NAME');
                dispatch(new ContentJob($jobData))->onQueue($contentQueueName);
            }
        }
        $vedio = $params['vedio'] ?? '';
        if ($vedio) {
            $this->checkUserAction($user_id, ContentNameEnum::VIDEO_INTRO);
            if ($vedio == 'delete') {
                $data['vedio'] = '';
                $data['vedio_cover'] = '';
                //同时在变更表删除
                $w = [
                    'user_id' => $user_id,
                    'content_name' => ContentNameEnum::VIDEO_INTRO,
                ];
                app('model_user_change_action')->where($w)->update(['status' => 0, 'del_time' => time()]);
                $this->deleteUserVerifyStatus($user_id, ContentNameEnum::VIDEO_INTRO);
            } else {
                $vedio_cover = $vedio . '?x-oss-process=video/snapshot,t_10000,m_fast';
                $filter_data = ['img' => $vedio_cover, 'tokenId' => $user_id];
                $res = FilterService::checkImage($filter_data);
                if ($res) {
                    throw new BasicException(21004);
                }

                //先审核后发布
                //                $data['vedio'] = $vedio;
                //                $data['vedio_cover'] = $vedio_cover;

                //保存用户变更记录
                $id = app('model_user_change_action')->insertGetId([
                    'user_id' => $user_id,
                    'url' => $vedio,
                    'other_data' => json_encode([
                        'vedio_cover' => $vedio_cover,
                    ]),
                    'content_name' => ContentNameEnum::VIDEO_INTRO,
                    'add_time' => time(),
                ]);
                $this->setUserVerifyStatus($user_id, ContentNameEnum::VIDEO_INTRO, [
                    'max_id' => $id,
                    'status' => 1,
                    'url' => $vedio,
                    'other_data' => json_encode([
                        'vedio_cover' => $vedio_cover,
                    ]),
                ]);
                $jobData = [
                    'user_id' => $user_id,
                    'key_id' => $id,
                    'content_type' => ContentTypeEnum::VIDEO,
                    'content_name' => ContentNameEnum::VIDEO_INTRO,
                    'content' => '',
                    'videos' => json_encode([$vedio]),
                ];
                $contentQueueName = env('CONTENT_QUEUE_NAME');
                dispatch(new ContentJob($jobData))->onQueue($contentQueueName);
            }
        }
        $nickname = $params['nickname'] ?? '';//昵称
        $nickname = str_replace("\n", '', $nickname);
        if ($nickname && $info->nickname != $nickname) {
            $this->checkUserAction($user_id, ContentNameEnum::NICKNAME);
            $isCheck = $this->getUserVerifyStatus($user_id, ContentNameEnum::NICKNAME);
            if (isset($isCheck['status']) && $isCheck['status'] == 1) {
                throw new BasicException(0, '您的昵称正在审核中,请耐心等候~');
            }
            if (mb_strlen($nickname, "utf-8") > 10) {
                throw new BasicException(21005);
            }
            $res = FilterService::checkNickname($nickname, $user_id);
            if ($res) {
                throw new BasicException(21006);
            }

            $check_nickname = app('model_user_data')->checkNickname($nickname, $user_id);
            if ($check_nickname > 0) {
                throw new BasicException(21007);
            }
            //保存用户变更记录
            $id = app('model_user_change_action')->insertGetId([
                'user_id' => $user_id,
                'url' => $nickname,
                'content_name' => ContentNameEnum::NICKNAME,
                'other_data' => json_encode([
                    'origin' => $info->nickname,
                ]),
                'add_time' => time(),
            ]);
            $this->setUserVerifyStatus($user_id, ContentNameEnum::NICKNAME, [
                'max_id' => $id,
                'status' => 1,
                'url' => $nickname,
                'other_data' => json_encode([
                    'origin' => $info->nickname,
                ]),
            ]);

            $jobData = [
                'user_id' => $user_id,
                'key_id' => $id,
                'content_type' => ContentTypeEnum::TEXT,
                'content_name' => ContentNameEnum::NICKNAME,
                'content' => $nickname,
                'content_origin' => $info->nickname,
                'machine_result' => FilterService::$riskLevel,
            ];
            $contentQueueName = env('CONTENT_QUEUE_NAME');
            dispatch(new ContentJob($jobData))->onQueue($contentQueueName);
            $data['nickname'] = $nickname;
        }
        if (isset($params['signature']) && $info->signature != $params['signature']) {
            $this->checkUserAction($user_id, ContentNameEnum::SIGNATURE);
            $signature = trim($params['signature']);
            if ($signature) {
                if (mb_strlen($signature, "utf-8") > 50) {
                    throw new BasicException(21008);
                }
                $isCheck = $this->getUserVerifyStatus($user_id, ContentNameEnum::SIGNATURE);
                if (isset($isCheck['status']) && $isCheck['status'] == 1) {
                    throw new BasicException(0, '您的签名正在审核中,请耐心等候~');
                }
                //验证敏感词
                $nickname = app('model_user_data')->getUserNickname($user_id);
                if (FilterService::checkSignature($signature, $user_id, $nickname)) {
                    throw new BasicException(21009);
                }

                //保存用户变更记录
                $id = app('model_user_change_action')->insertGetId([
                    'user_id' => $user_id,
                    'url' => $signature,
                    'content_name' => ContentNameEnum::SIGNATURE,
                    'add_time' => time(),
                ]);
                $this->setUserVerifyStatus($user_id, ContentNameEnum::SIGNATURE, [
                    'max_id' => $id,
                    'status' => 1,
                    'url' => $signature,
                ]);

                $jobData = [
                    'user_id' => $user_id,
                    'key_id' => $id,
                    'content_type' => ContentTypeEnum::TEXT,
                    'content_name' => ContentNameEnum::SIGNATURE,
                    'content' => $signature,
                    'content_origin' => $info->signature,
                    'machine_result' => FilterService::$riskLevel,
                ];
                $contentQueueName = env('CONTENT_QUEUE_NAME');
                dispatch(new ContentJob($jobData))->onQueue($contentQueueName);

                $data['signature'] = $signature;
            } else {
                $data['signature'] = '';
            }
        }
        if (isset($params['birthday'])) {
            $data['birthday'] = $params['birthday'];
        }
        if (isset($params['constellation'])) {
            $data['constellation'] = $params['constellation'];
        }
        if (isset($params['profession'])) {
            $data['profession'] = $params['profession'];
        }
        if (isset($params['province_id'])) {
            $data['province_id'] = $params['province_id'];
        }
        if (isset($params['city_id'])) {
            $data['city_id'] = $params['city_id'];
        }
        if (isset($params['county_id'])) {
            $data['county_id'] = $params['county_id'];
        }
        /*修改头像调用独立的接口
         * if (isset($params['head_picture'])) {
            $head_picture = $params['head_picture'];
            if ($head_picture) {
                app('model_user_data')->checkAvatar($user_id, $head_picture);
                $data['head_picture'] = htmlspecialchars_decode($head_picture);
            }
        }*/
        /*修改相册调用独立的接口
         * if (isset($params['user_photo'])) {
            $user_photo = $params['user_photo'];
            //获取相册
            $user_photos = app('model_user_data')->where('user_id', $user_id)->value('user_photo');
            if ($user_photos && $user_photos != "N;") {
                $picture = unserialize($user_photos);
                $arr = explode(',', $user_photo);
                $picture = array_merge($picture, $arr);
            } else {
                $picture = explode(',', $user_photo);
            }
            $data['user_photo'] = serialize($picture);
        }*/
        if ($info) {
            if (!empty($data)) {
                app('model_user_data')->where($where)->update($data);
            }

            if (isset($data['sex'])) {
                app('model_user_change')->addChange($user_id, $info['sex'], $data['sex'], 3);
            }

            if ($user_no) {
                $parent_id = app('model_user_data')->where('user_code', $user_no)->value('user_id');
                if (!$parent_id) {
                    throw new BasicException(21011);
                }
                if ($parent_id == $user_id) {
                    throw new BasicException(21012);
                }
                app('model_user')->where('user_id', $user_id)->update(['parent_id' => $parent_id]);
            }

            if (isset($data['nickname']) && $data['nickname'] != $info['nickname']) {
                app('model_user_change')->addChange($user_id, $info['nickname'], $data['nickname'], 2);
            }
        } else { //不存在 新增
            $data['user_id'] = $user_id;
            app('model_user_data')->insert($data);
        }
        RedisService::clearUserInfo($user_id);
    }

    public function deleteUserVerifyStatusByKeyId($key_id, $user_id, $status)
    {
        if (empty($key_id)) {
            return false;
        }
        //删除用户缓存
        app('redis')->del(sprintf(RedisKeyEnum::USER_INFO, $user_id));
        $hasRecord = app('model_user_change_action')->where([
            'id' => $key_id,
            'user_id' => $user_id,
        ])->first();
        if (empty($hasRecord)) {
            return false;
        }
        $hasRecord = $hasRecord->toArray();
        $contentName = $hasRecord['content_name'];
        //        $maxInfo =  $this->getUserVerifyStatus($user_id,$contentName);
        $maxInfo = app('model_user_change_action')->where([
            'user_id' => $user_id,
            'content_name' => $contentName,
        ])->orderBy('id', 'desc')->first();

        $maxInfo = empty($maxInfo) ? [] : $maxInfo->toArray();
        $status = $status == 2 ? 3 : 2;   //2是审核拒绝对应3 1是审核通过对应2
        app('model_user_change_action')->where([
            'id' => $key_id,
        ])->update([
            'status' => $status,
        ]);
        $max_id = $maxInfo['id'] ?? 0;
        if ($key_id >= $max_id) {
            $this->deleteUserVerifyStatus($user_id, $contentName);

            return $maxInfo;
        }

        return false;
    }

    public function deleteUserVerifyStatus($user_id, $contentName = '')
    {
        $redisKey = RedisKeyEnum::USER_VERIFY_STATUS . $user_id;
        $redis = app('redis');
        //        $redis = new \Redis();
        if (!$redis->exists($redisKey)) {
            $this->initUserVerifyStatus($user_id);
        }

        $redis->hDel($redisKey, $contentName);
    }

    public function setUserVerifyStatus($user_id, $contentName = '', $data = [])
    {
        $redisKey = RedisKeyEnum::USER_VERIFY_STATUS . $user_id;
        $redis = app('redis');
        if (!$redis->exists($redisKey)) {
            $this->initUserVerifyStatus($user_id);
        }
        $verifyInfo = $this->getUserVerifyStatus($user_id, $contentName);
        if (!empty($verifyInfo)) {
            if ($verifyInfo['max_id'] > $data['max_id']) {
                $data['max_id'] = $verifyInfo['max_id'];
                $data['status'] = $verifyInfo['status'];
                $data['url'] = $verifyInfo['url'];
                $data['other_data'] = $verifyInfo['other_data'] ?? '';
            }
        }
        if ($data) {
            if (isset($data['other_data'])) {
                if (!is_array($data['other_data'])) {
                    $data['other_data'] = json_decode($data['other_data'], true);
                }
            } else {
                $data['other_data'] = [];
            }
        }
        $redis->hSet($redisKey, $contentName, json_encode($data));
    }

    public function incMoney($userCode, $money)
    {
        $userId = UserData::query()->where("user_code", $userCode)->value("user_id");
        if (!$userId) {
            throw new BasicException(-1, "用户不存在");
        }
        User::query()->where("user_id", $userId)->update(["money" => DB::raw("money + $money")]);
    }

    public function getUserVerifyStatus($user_id, $contentName = '')
    {
        $redisKey = RedisKeyEnum::USER_VERIFY_STATUS . $user_id;
        $redis = app('redis');
        //        $redis = new \Redis();
        if ($contentName) {
            $data = $redis->hget($redisKey, $contentName);
            $data = empty($data) ? [] : json_decode($data, true);
        } else {
            $data = $redis->hGetAll($redisKey);
            foreach ($data as $k => $v) {
                $data[$k] = json_decode($v, true);
            }
        }

        return $data;
    }

    public function initUserVerifyStatus($user_id)
    {
        //
        $where = [
            'user_id' => $user_id,
        ];
        //取最新一条的变更记录
        //        $res = DB::select("SELECT * FROM ln_user_change_action WHERE id IN (SELECT MAX(id) FROM ln_user_change_action GROUP BY content_name where user_id=$user_id");
        $maxId = app('model_user_change_action')->select(['id', 'content_name'])->where($where)->groupBy('content_name', 'id')->max('id');

        if (empty($maxId)) {
            return [];
        }
        $data = app('model_user_change_action')->where('id', $maxId)->first();
        $redisKey = RedisKeyEnum::USER_VERIFY_STATUS . $user_id;
        $redis = app('redis');
        //        $redis = new \Redis();
        foreach ($data as $k => $v) {
            $d = [
                'status' => $v['status'],
                'max_id' => $v['id'],
                'url' => $v['url'],
                'other_content' => json_decode($v['other_content'], true) ?? '',
            ];
            $redis->hSet($redisKey, $v['content_name'], json_encode($d));
        }
    }

    public function verifyGender($user_id)
    {
        $change_count = app('model_user_change')->getChangeCount($user_id, 3);

        return $change_count >= 1 ? 0 : 1;
    }

    public function isDebug($code)
    {
        if ($code == "dBo5FxAfk5m0") {
            return true;
        }
        return false;
    }

    public function vipInfo($user_id)
    {
        $user = app('model_user')->with('user_data:user_id,nickname,head_picture')->where('user_id', $user_id)->first();
        $rank_id = $user->upgradeVip($user_id); //调用升级方法
        //获取已经消费总额
        $info['exp'] = round(floatval(app('model_user_exp')->getUserExp($user_id)), 2);

        //达到当前等级所需经验
        $current_exp = round(floatval(app('model_grade_config')->getGradeExp($rank_id)), 2);
        //达到下一等级所需经验
        $next_exp = round(floatval(app('model_grade_config')->getGradeExp($rank_id + 1)), 2);

        $info['diff'] = $info['exp'] > $next_exp ? 0 : round($next_exp - $info['exp'], 2);

        if ($info['exp'] == 0) {
            $info['percent'] = 0;
        } else {
            $info['percent'] = ($info['exp'] > $next_exp || floor($info['exp'] - $current_exp) <= 0) ? 100 : (floor(($info['exp'] - $current_exp) / ($next_exp - $current_exp) * 100));
        }
        $info['current'] = app('model_grade_config')->getGradeName($rank_id);
        $info['next'] = app('model_grade_config')->getGradeName($rank_id + 1);
        $info['rank_id'] = intval($rank_id);
        $info['rank_label'] = app('model_grade_config')->getGradeVName($info['rank_id']);
        $info['next_rank_label'] = app('model_grade_config')->getGradeVName($info['rank_id'] + 1);
        $info['rank_icon'] = app('model_grade_config')->getGradeIcon($info['rank_id']);
        $info['rank_big_icon'] = app('model_grade_config')->getGradeBigIcon($info['rank_id']);
        $info['nickname'] = $user->user_data->nickname ?? '';
        $info['head_picture'] = $user->user_data->head_picture ?? '';
        $info['rank_info'] = app('model_user')->rankInfo($user_id);

        return $info;
    }

    public function charmInfo($user_id)
    {
        $user = app('model_user')->with('user_data:user_id,nickname,head_picture')->where('user_id', $user_id)->first();
        $charm_id = $user->upCharmVip($user_id); //调用升级方法
        //获取已经消费总额
        $info['exp'] = round(floatval(app('model_user_charm')->getUserCharm($user_id)), 2);
        //达到当前等级所需经验
        $current_exp = round(floatval(app('model_charm_config')->getCharmExp($charm_id)), 2);
        //达到下一等级所需经验
        $next_exp = round(floatval(app('model_charm_config')->getCharmExp($charm_id + 1)), 2);
        $info['diff'] = $info['exp'] > $next_exp ? 0 : round($next_exp - $info['exp'], 2);

        if ($info['exp'] == 0) {
            $info['percent'] = 0;
        } else {
            $info['percent'] = ($info['exp'] > $next_exp || floor($info['exp'] - $current_exp) <= 0) ? 100 : (floor(($info['exp'] - $current_exp) / ($next_exp - $current_exp) * 100));
        }
        $info['current'] = app('model_charm_config')->getCharmName($charm_id) ?? 0;
        $info['next'] = app('model_charm_config')->getCharmName($charm_id + 1);
        $info['charm_id'] = intval($charm_id);
        $info['charm_label'] = app('model_charm_config')->getCharmVName($info['charm_id']);
        $info['next_charm_label'] = app('model_charm_config')->getCharmVName($info['charm_id'] + 1);
        $info['charm_icon'] = app('model_charm_config')->getCharmIcon($info['charm_id']);
        $info['charm_big_icon'] = app('model_charm_config')->getCharmBigIcon($info['charm_id']);
        $info['nickname'] = $user->user_data->nickname ?? '';
        $info['head_picture'] = $user->user_data->head_picture ?? '';
//        $info['charm_info'] = app('model_user')->rankInfo($user_id);
        return $info;
    }

    //type: 1.拉黑  2.取消
    public function addBlackUser($user_id, $black_id, $type)
    {
        $info = app('model_black_list')->checkUserBlack($user_id, $black_id);
        if ($type == 1) {
            if ($info) {
                throw new BasicException(21015);
            }
            $data['black_id'] = $black_id;
            app('model_black_list')->insert([
                'user_id' => $user_id,
                'black_id' => $black_id,
                'add_time' => Carbon::now()->timestamp,
            ]);
            //删除好友关系
            $where['friend_id'] = $user_id;
            $where['user_id'] = $black_id;
            app('model_friend')->where($where)->delete();
            $wheres['friend_id'] = $black_id;
            $wheres['user_id'] = $user_id;
            app('model_friend')->where($wheres)->delete();

            RedisService::delFriend($user_id, $black_id);

            //取消关注
            $map = [
                'user_id' => $user_id,
                'followed_user' => $black_id,
            ];
            app('model_follow')->where($map)->delete();
            $other_map = [
                'user_id' => $black_id,
                'followed_user' => $user_id,
            ];
            app('model_follow')->where($other_map)->delete();
            app('rongcloud')->whitelist($user_id, [$black_id]);
            app('rongcloud')->whitelist($black_id, [$user_id]);

        }
        if ($type == 2) {
            if (!$info) {
                throw new BasicException(21016);
            }
            $where['user_id'] = $user_id;
            $where['black_id'] = $black_id;
            app('model_black_list')->where($where)->delete();
//            app('rongcloud')->whitelistADD($user_id, [$black_id]);
//            app('rongcloud')->whitelistADD($black_id, [$user_id]);
        }
        app('redis')->del([
            'user:friend:count:' . $user_id,
            'user:friend:count:' . $black_id,
            'user:follow:count:' . $user_id,
            'user:follow:count:' . $black_id,
            'user:fans:count:' . $user_id,
            'user:fans:count:' . $black_id,
        ]);
    }

    public function getUserDetails($user_id)
    {
        $field = [
            'user_id',
            'mobile',
            'user_no',
            'parent_id',
            'rank_id',
            'emchat_username',
            'emchat_password',
            'password',
            'money',
            'earnings',
            'second_password',
            'role',
            'register_time',
            'nobility',
            'charm_id',
            'withdraw_status'
        ];
        $info = app('model_user')->where('user_id', $user_id)->select($field)->first();
//        if(!$info['withdraw_status']){
//            $info['withdraw_status'] = RedisService::checkGuildUser($user_id);
//        }

        $info['withdraw_status'] = 1;
        if ($info) {
            $info = $info->toArray();
            if ($info['rank_id'] > 0) {
                $info['rank_icon'] = app('model_grade_config')->getGradeIcon($info['rank_id']);
            } else {
                $info['rank_icon'] = '';
            }

            $info['charm_icon'] = $info['charm_id'] > 0 ? app('model_charm_config')->getCharmIcon($info['charm_id']) : '';

            if ($info['nobility'] > 0) {
                $info['nobility_icon'] = app('model_nobility')->getNobilityIcon($info['nobility']);
            } else {
                $info['nobility_icon'] = '';
            }

            if ($info['password']) {
                $info['is_password'] = 1;
            } else {
                $info['is_password'] = 0;
            }
            unset($info['password']);
            $info['role'] = $info['role'] == 2 ? 5 : 1;
            $info['user_is_new'] = app('model_user')->checkUserNew($user_id);
            unset($info['register_time']);

            $rank_info = app('model_user')->rankInfo($user_id);

            $info['second_password'] = $info['second_password'] ? 1 : 0;
            //获取详细资料
            $result = app('model_user_data')->where('user_id', $info['user_id'])->first();
            if (!$result) {
                return [];
            }
            $result = $result->toArray();
            $info['sex'] = $result['sex'];
            $info['nickname'] = $result['nickname'];
            $info['head_picture'] = $result['head_picture'];
            $user_photo_list = app('model_user_photo')->where(['user_id' => $user_id, 'state' => 1])->pluck('url');
            $info['photo_count'] = $user_photo_list->isEmpty() ? 0 : $user_photo_list->count();
            $info['user_photo'] = $user_photo_list->isEmpty() ? [] : $user_photo_list->toArray();
            $info['signature'] = $result['signature'];
            $info['birthday'] = $result['birthday'];
            $info['constellation'] = $result['constellation'];
            $info['profession'] = $result['profession'];
            $info['province_id'] = $result['province_id'];
            $info['city_id'] = $result['city_id'];
            $info['county_id'] = $result['county_id'];
            $info['province'] = $result['province_id'] > 0 ? app('model_region')->getRegionNameById($result['province_id']) : '';
            $info['city'] = $result['city_id'] > 0 ? app('model_region')->getRegionNameById($result['city_id']) : '';
            $info['county'] = $result['county_id'] > 0 ? app('model_region')->getRegionNameById($result['county_id']) : '';
            $info['real_name'] = $result['real_name'];
            $info['identity_number'] = $result['identity_number'];
            $info['real_name'] = $result['real_name'];
            $info['user_code'] = $result['user_code'];
            //获取通知设置
            $config = app('model_user_config')->getUserInform($user_id);
            $info['broadcast'] = $config['broadcast'] ?? 2;           //开播通知 1.开 2.关
            $info['fans'] = $config['fans'] ?? 2;                //新粉丝通知  1.开  2.关
            $info['visit'] = $config['visit'] ?? 2;               //访问隐身  1.开 2.关
            $info['online'] = $config['online'] ?? 2;              //在线隐身  1.开  2.关
            $info['chat'] = $config['chat'] ?? 2;                //聊天室隐身 1.开  2.关
            $info['news_voice'] = $config['news_voice'] ?? 2;          //新消息声音提现 1开启 2关闭
            $info['news_vibrate'] = $config['news_vibrate'] ?? 2;        //新消息震动提醒 1开启 2关闭
            $info['only_friend'] = $config['only_friend'] ?? 2;         //是否只有好友才能发送消息 1开启 2关闭
            $info['is_private_chat'] = $config['is_private_chat'] ?? 2;    //是否只有好友才能发送消息 1开启 2关闭
            $info['is_open_giftwall'] = $config['is_open_giftwall'] ?? 1;   //是否开启礼物墙 1开启 2关闭
            //获取用户爵位信息
            $info['nobility_name'] = $rank_info['nobility_name'] ?? '';

            $info['withdraw_earnings'] = sprintf("%.2f", $info['earnings'] / app('model_config')->getValue('GOLD_FEE'));

            $user_room = app('model_user_room')->getUserRoom($user_id);
            $info['own_room_id'] = $user_room->id ?? null;
            $info['own_room_password'] = isset($user_room->password) && $user_room->password ? 1 : 0;

            $info['is_invisible'] = isRoomInvisibleUser($user_id);  //0无权限1隐身2不隐身
            $info['rank_invisible'] = isRoomRankInvisible($user_id);  //0无权限1隐身2不隐身
            $info['special'] = app('model_user')->special($user_id);
            $info['is_guild_user'] = RedisService::checkGuildUser($user_id);
            // 微信支付 app_id
            $info['wx_app_id'] = app('model_config')->getValue('WX_APP_ID') ?? '';
        }
        $info['rank_info'] = $rank_info ?? [];
        $info['user_nobility_expire'] = app('model_user_nobility')->getExpire($user_id);
        $info['sign_first'] = app('repo_activity_sign')->checkSignFirst($user_id);
        $info['is_sociaty_master'] = app('model_user')->checkSociatyMaster($user_id);

        // 获取配置
        $sendNumberLevel = app('model_config')->getValue("CHAT_SEND_NUMBER_LEVEL");
        $info['can_send_number'] = 0;
        $sendNumberLevel = $sendNumberLevel ?? 0;
        $rank_info["rank_id"] = $rank_info["rank_id"] ?? 0;
        if ($sendNumberLevel <= $rank_info["rank_id"]) {
            $info['can_send_number'] = 1;
        }
        $info['sms_sign'] = app('model_config')->getValue("SMS_SIGN");

        //用户是否可以截图 默认可用
        $info['screen_capture'] = true;
        $user_screen_capture = app('model_config')->getValue("USER_SCREEN_CAPTURE");
        if ($user_screen_capture !== '' && !$user_screen_capture) {
            $info['screen_capture'] = false;
        }

        $info['title_gift_info'] = $this->getUserTitleNowInfo($user_id);
        $info['recharge_icon'] = RedisService::getUserRechargeIcon($user_id);

        return $info;
    }

    public function checkCanSendNumber(int $userId): int
    {
        $sendNumberLevel = app('model_config')->getValue("CHAT_SEND_NUMBER_LEVEL");
        $rank = User::query()->where("user_id", $userId)->value("rank_id");
        if (empty($rank) || $sendNumberLevel > $rank) {
            return 0;
        }
        return 1;
    }

    //添加订单
    public function rechargeMoney($user_id, $money, $type = 1, $bddid = '')
    {
        $gold_fee = app('model_config')->getValue('GOLD_FEE');

        // 守护配置
        $protectConfig = json_decode(app('model_config')->getValue("PROTECT_CONFIG"), 1);
        $protectMoney = $protectConfig["protect_money"] ?: 0;

        if (!empty($protectMoney) && $protectMoney == $money) {
            $protectType = 2;
            $gold_actual = 0;
        } else {
            $protectType = 1;
            $gold_actual = $money * $gold_fee;
            $reduct_point = app('model_config')->getValue('RECHARGE_REDUCE_POINT');
            if ($reduct_point > 0) {
                $gold_actual = round($gold_actual * (1 - $reduct_point / 100), 2);
            }
        }

        // 小额充值次数及金额设定
        $RECHARGE_SMALL_CONFIG = app("model_config")->getValue("RECHARGE_SMALL_AMOUNT_NUM");
        $RECHARGE_SMALL_CONFIG = !empty($RECHARGE_SMALL_CONFIG) ? json_decode($RECHARGE_SMALL_CONFIG, true) : [];
        if (!empty($RECHARGE_SMALL_CONFIG) && $RECHARGE_SMALL_CONFIG['status'] == 0) {
            $config_small_amount = isset($RECHARGE_SMALL_CONFIG['amount']) && is_numeric($RECHARGE_SMALL_CONFIG['amount']) && $RECHARGE_SMALL_CONFIG['amount'] > 0 ? $RECHARGE_SMALL_CONFIG['amount'] : 50;
            $config_small_new_num = isset($RECHARGE_SMALL_CONFIG['num']) && is_numeric($RECHARGE_SMALL_CONFIG['num']) && $RECHARGE_SMALL_CONFIG['num'] > 0 ? $RECHARGE_SMALL_CONFIG['num'] : 3;
            $config_small_time_num = isset($RECHARGE_SMALL_CONFIG['time_num']) && is_numeric($RECHARGE_SMALL_CONFIG['time_num']) && $RECHARGE_SMALL_CONFIG['time_num'] > 0 ? $RECHARGE_SMALL_CONFIG['time_num'] : 3;
            $redisTimeLimitKey = "user:recharge_timelimit:" . $user_id;
            #是否在充值限制名单中
            if (app("redis")->exists($redisTimeLimitKey) && $money < $config_small_amount) {
                throw new BasicException(-1, "充值排队中！");
            }
            if ($money <= $config_small_amount) {
                $user_info = app('redis')->hgetall(sprintf(RedisKeyEnum::USER_INFO, $user_id));
                if (empty($user_info) || !isset($user_info['register_time']) || !isset($user_info['user_code']) || !isset($user_info['nickname'])) {
                    $user_info = app("model_user")->from(app("model_user")->getTable() . ' as a')
                        ->leftJoin(app("model_user_data")->getTable() . ' as b', 'a.user_id', '=', 'b.user_id')
                        ->select("a.register_time", "b.user_code", "b.nickname")->where('a.user_id', $user_id)->first();
                }
                $SHOW_CONFIG = app("model_config")->getValue("SHOW_NEW_USER");#新用户配置信息
                $SHOW_CONFIG = !empty($SHOW_CONFIG) ? json_decode($SHOW_CONFIG, true) : [];
                $new_days = isset($SHOW_CONFIG['register_days']) && $SHOW_CONFIG['register_days'] > 0 ? $SHOW_CONFIG['register_days'] : 3;
                $userRechargeModel = app("model_user_recharge")::query();
                #新用户单一小额充值限制
                if (time() - $user_info['register_time'] < 60 * 60 * 24 * $new_days) {
                    $recharge_small_new_num = $userRechargeModel
                        ->where('user_id', $user_id)
                        ->where('status', 2)
                        ->where('money', '<=', $config_small_amount)->count();
                    if ($recharge_small_new_num > $config_small_new_num) {
                        throw new BasicException(-1, "支付失败！！！");
                    }
                }
                #小额充值分钟限制
//            $one_min_ago    = strtotime("-1 minute");
                $one_min_ago = time() - ($config_small_time_num * 60);
                $recharge_small_time_num = app("model_user_recharge")::query()
                    ->where('user_id', $user_id)
                    ->where('status', 2)
                    ->where('money', '<=', $config_small_amount)
                    ->where('add_time', '>=', $one_min_ago)
                    ->count();
                if ($recharge_small_time_num > $config_small_new_num) {
                    #是否为注册2小时内或者未改名，则直接封禁
                    app("redis")->setex($redisTimeLimitKey, $config_small_time_num * 60, $user_id);
                    throw new BasicException(-1, "充值排队中！");
                }
            }
        }

        $user_code = app('model_user_data')->getUserCode($user_id);
        $user_recharge_zero = app('model_config')->getValue('USER_RECHARGE_ZERO');
        if (is_array($user_recharge_zero) && in_array($user_code, $user_recharge_zero)) {
            // 测试 一万块
            $money = 10000;
            $gold_actual = 1;
        }

        $businessConfigService = new BusinessConfigService();
        $payType = $type == 1 ? $businessConfigService::PAY_TYPE_ALI : $businessConfigService::PAY_TYPE_WECHAT;
        $businessConfig = $businessConfigService->getOne($user_id, $money, $payType);

        if ($businessConfig === null || empty($businessConfig->params)) {
            throw new BasicException(-1, '未获取到商户配置');
        }
//        return $businessConfig;

        // 获取到当前的id  去redis查是否达到 的多少钱
        // 支付回调的配置没有进行 是否开启判断 可直接在这里使用
        // 回调 使用 有序集合 处理 存一下redis 那个商户我这边 在redis   商户  1  1000  商户 2  0  商户 3  0

        if ($payType == $businessConfigService::PAY_TYPE_WECHAT) {
            $key = "WX_RECHARGE_CAPPING";
            $redis = app('redis');
            if ($redis->exists($key)) {
                $wx_recharge = app('model_config')->getValue('WX_RECHARGE_CAPPING');
                $recharge = $redis->zscore($key, $businessConfig->id);
                if ($recharge >= $wx_recharge) {
                    // 匹配下一个 商户  再次记录一下
                    if (!$redis->exists(BusinessConfigService::PAY_CHANNEL_DATA)) {
                        // 设置 对标 商户 id 和 1 = > id  后台配置就直接跳转
                        $business_arr = BusinessConfig::query()->where('pay_type', $payType)
                            ->where('is_status', 1)
                            ->get()->pluck('id')->toArray();
                        app('redis')->set(BusinessConfigService::PAY_CHANNEL_DATA, json_encode($business_arr));
                    } else {
                        $business_arr = json_decode(app('redis')->get(BusinessConfigService::PAY_CHANNEL_DATA), true);
                    }
                    $business_count = count($business_arr);
                    if (empty($business_count)) throw new BasicException(-1, '未获取到商户配置');
                    $business_key = array_search($businessConfig->id, $business_arr);
                    $business_id = $business_count <= $business_key + 1 ? $business_arr[0] : $business_arr[$business_key + 1];
                    if ($business_count <= $business_key + 1) {
                        // 修改 充值通道的分数
                        // 的分数
                        foreach ($business_arr as $v) {
                            $redis->zadd($key, [$v => 0]);
                        }
                    }
                    $businessConfig = $businessConfigService->getNEWOne($user_id, $money, $payType, $business_id);
                }
            } else {
                // 成员是否存在 和 获取成员的分数
//            zscore($key, $member);
                // 增加成员的分数
                // zincrby($sortedSet, $score, $member);
                // 删调成员
                // zrem('my_sorted_set', 'member1');
                // 不存在 进行 和 金额
                $redis->zadd($key, [$businessConfig->id => 0]);
            }
        }

        if ($businessConfig === null || empty($businessConfig->params)) {
            throw new BasicException(-1, '未获取到商户配置');
        }
        //根据ip判断是否异地充值
        $check_ip_result = app('model_user_recharge')->checkIpRecharge(UID, $bddid);
        if ($check_ip_result['status'] != 1) {
            throw new BasicException(-1, $check_ip_result['info']);
        }
        //充值判断 该用户是否达到封禁标准
        $recharge_ban_msg = app('model_user')->recharge_ban_msg(UID);
        if ($recharge_ban_msg) {
            throw new BasicException(-1, $recharge_ban_msg);
        }

        $data['gold'] = $gold_actual;
        $data['money'] = $money;
        $data['user_id'] = $user_id;
        // $data['type'] = $type;
//        $data['type'] = $type == 1? 6: 7; // 6. 杉徳支付宝h5, 7.杉徳微信h5, 8.杉徳支付宝App, 9.杉徳微信App
        $data['product_type'] = $protectType;
        $data['order_sn'] = $orderSn = strtoupper(date('Ymd', time())) . substr(time(), -5) . substr(microtime(), 2, 5) . sprintf('%02d', rand(0, 99));
        $data['add_time'] = NOW_TIME;
        $data['account_type'] = getRechargeMerchant($type);
        $data['bddid'] = $bddid;
        $data['business_config_id'] = $businessConfig->id;
        $data['recharge_ip_info'] = $check_ip_result['this_recharge_ip_info'];

        $data['type'] = $businessConfigService->getUserRechargeType($payType, $businessConfig->pay_channel);


        $model = app('model_user_recharge')->create($data);

        return (string)$model->id;
    }

    //

    /**
     * 验证用户支付 黑名单
     * @param string $iphone
     * @param string $ip
     * @param string $bddid
     * @param string $IDCard
     * @param array $open_id
     * @return bool
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public function verificationPay($iphone = '', $ip = '', $bddid = '', $IDCard = '', $open_id = [])
    {
        $status = true;
        $redis = app('redis');
        if ($iphone != '') {
            $key1 = 'wx:change:blacklist1';
            if ($redis->exists($key1) && in_array($iphone, json_decode($redis->get($key1), true) ?? [])) return false;
        }
        if ($ip != '') {
            $key2 = 'wx:change:blacklist2';
            if ($redis->exists($key2) && in_array($ip, json_decode($redis->get($key2), true) ?? [])) return false;
        }
        if ($bddid != '') {
            $key5 = 'wx:change:blacklist5';
            if ($redis->exists($key5) && in_array($bddid, json_decode($redis->get($key5), true) ?? [])) return false;
        }
        if ($IDCard != '') {
            $key4 = 'wx:change:blacklist4';
            if ($redis->exists($key4) && in_array($IDCard, json_decode($redis->get($key4), true) ?? [])) return false;

        }
        if (!empty($open_id)) {
            $key3 = 'wx:change:blacklist3';
            if ($redis->exists($key3) && collect(json_decode($redis->get($key3), true) ?? [])->intersect($open_id)->isNotEmpty()) return false;
        }
        return $status;
    }

    //添加订单
    public function rechargeGold($userId, $number, $appVersion, $type = 3, $bddid = '')
    {
        $gold_fee = app('model_config')->getValue('GOLD_FEE');
        if ($type != 3) {
            $gold_actual = $number;
            $reduct_point = app('model_config')->getValue('RECHARGE_REDUCE_POINT');
            if ($reduct_point > 0) {
                $gold_actual = round($number * (1 - $reduct_point / 100), 2);
            }
            $money = $number / $gold_fee;
        } else {
            $appVersionNumber = str_replace('.', '', $appVersion);
            $ios_version = json_decode(app('model_config')->getValue('IOS_VERSION'), true);
            $ios_other_version = $ios_version['otherVersion'] ?? 0;//后台配置的版本号
            $ios_other_version = str_replace('.', '', $ios_other_version);
            /*if ($appversion_number <= $ios_other_version) {
//                $message = $appversion_number < 300 ? 'Ios支付通道正在维护中' : 'http://www.yutangwl.com/web/recharge';
                $message = 'Ios支付通道正在维护中';
                return V(0, $message);
            }*/
            $money = $number * 6;
            $gold_actual = $number;
        }

        //        if (APP_STATUS != 'production') {
        $user_code = app('model_user_data')->getUserCode($userId);
        $user_recharge_zero = app('model_config')->getValue('USER_RECHARGE_ZERO');
        if (is_array($user_recharge_zero) && in_array($user_code, $user_recharge_zero)) {
            $money = 0.01;
            $gold_actual = 1;
        }
        //        }

        $data['gold'] = $gold_actual;
        $data['money'] = $money;
        $data['user_id'] = UID;
        $data['type'] = $type;
        $data['order_sn'] = strtoupper(date('Ymd', time())) . substr(time(), -5) . substr(microtime(), 2, 5) . sprintf('%02d', rand(0, 99));
        $data['account_type'] = getRechargeMerchant($type);
        $data['bddid'] = $bddid;
        $model = app('model_user_recharge')->create($data);

        $return = $type == 3 ? $data['order_sn'] : (string)$model->id;

        return $return;
    }

    //获取用户黑名单列表
    public function getUserBlackList($user_id, $keyword = '', $user_code = '')
    {
        $where = [
            ['b.user_id', $user_id],
        ];
        if ($keyword) {
            $where[] = ['u.nickname', 'like', $keyword . '%'];
        }
        if ($user_code) {
            $where[] = ['us.user_code', $user_code];
        }
        $list = app('model_black_list')
            ->from(app('model_black_list')->getTable() . " as b")
            ->selectRaw('b.id,b.black_id,u.nickname,u.head_picture,u.sex,u.signature,u.birthday,us.emchat_username,us.offline_time')
            ->join('ln_user as us', 'us.user_id', '=', 'b.black_id')
            ->join('ln_user_data as u', 'u.user_id', '=', 'b.black_id')
            ->where($where)->orderBy('b.add_time', 'desc')->get();

        $return_data = [];
        if (!$list->isEmpty()) {
            $list = $list->toArray();
            $list = data_letter_sort($list, 'nickname');
            foreach ($list as $k => $v) {
                $data = [];
                foreach ($v as $vv) {
                    $offlineTime = $vv['offline_time'];
                    $vv['age'] = birthToAge($vv['birthday'], 1);
                    $vv['tag'] = $k == '#' ? '' : $k;
                    $vv['is_online'] = $offlineTime == 0 ? 1 : 0;
                    unset($vv['birthday']);
                    $data[] = $vv;
                }
                $return_data[] = [
                    'index' => $k,
                    'item' => $data,
                ];
            }
        }

        return $return_data;
    }

    public function updateAvatar($user_id, $avatar)
    {
        $this->checkUserAction($user_id, ContentNameEnum::HEAD_PICTURE);

        //判断是否有正在审核中的记录
        $isCheck = $this->getUserVerifyStatus($user_id, ContentNameEnum::HEAD_PICTURE);
        if (isset($isCheck['status']) && $isCheck['status'] == 1) {
            // throw new BasicException(0, '您的头像正在审核中,请耐心等候~'); // todo 调试
        }

        $limit = true;//是否限制每日修改次数
        $user_not_limit = app('model_config')->getValue('USER_AVATAR_NOT_LIMIT');
        if (!empty($user_not_limit) && is_array($user_not_limit)) {
            $user_code = app('model_user_data')->getUserCode($user_id);
            if (in_array($user_code, $user_not_limit)) {
                $limit = false;
            }
        }

        $check = app('redis')->get('u:avatar:' . $user_id);
        if ($check >= 2 && $limit) {
            // throw new BasicException(400003); // todo 调试
        }

        if (FilterService::checkHeadPicture($avatar, $user_id)) {
            throw new BasicException(21004);
        }

        $now_time = Carbon::now()->timestamp;
        $head_picture = app('model_user_data')->getUserHeadPicture($user_id);
        $id = app('model_user_avatar')->insertGetId([
            'user_id' => $user_id,
            'change_from' => $head_picture,
            'change_to' => $avatar,
            'add_time' => $now_time,
        ]);
        $expired_time = Carbon::tomorrow()->timestamp - $now_time;
        $count = 1;
        if ($check > 0) {
            $count = $check + 1;
        }
        app('redis')->setex('u:avatar:' . $user_id, $expired_time, $count);
        RedisService::clearUserInfo($user_id);

        //保存用户变更记录
        $changeId = app('model_user_change_action')->insertGetId([
            'user_id' => $user_id,
            'url' => $avatar,
            'other_data' => json_encode([
                'origin' => $head_picture,
            ]),
            'content_name' => ContentNameEnum::HEAD_PICTURE,
            'add_time' => time(),
        ]);
        $this->setUserVerifyStatus($user_id, ContentNameEnum::HEAD_PICTURE, [
            'max_id' => $id,
            'status' => 1,
            'url' => $avatar,
            'other_data' => json_encode([
                'origin' => $head_picture,
            ]),
        ]);

        $jobData = [
            'user_id' => $user_id,
            'key_id' => $id . '|' . $changeId,
            'content_type' => ContentTypeEnum::PICTURE,
            'content_name' => ContentNameEnum::HEAD_PICTURE,
            'pictures' => json_encode([$avatar]),
            'content_origin' => $head_picture,
            'machine_result' => FilterService::$riskLevel,
        ];
        $contentQueueName = env('CONTENT_QUEUE_NAME');
        dispatch(new ContentJob($jobData))->onQueue($contentQueueName);
    }

    /*public function nobilityInfo($user_id)
    {
        $info  = app('model_user_nobility')->userInfo($user_id);
        $renew = [];
        if ($info) {
            $info['expired_time'] = date('Y-m-d', $info['expired_time']);
            $ratio                = app('model_config')->getValue('GOLD_FEE');
            $renew_base           = $info['renew'] * $ratio;
            $rebate_base          = $info['renew'] * $info['rebate'] / 100 * $ratio;
            $renew                = [
                ['day' => 30, 'price' => $renew_base * 1, 'rebate' => $rebate_base * 1],
                ['day' => 90, 'price' => $renew_base * 3, 'rebate' => $rebate_base * 3],
                ['day' => 180, 'price' => $renew_base * 6, 'rebate' => $rebate_base * 6],
            ];
            unset($info['price']);
            unset($info['renew']);
            unset($info['rebate']);
        } else {
            $info = [
                "nobility_id"      => 0,
                "expired_time"     => "",
                "state"            => 0,
                "nobility_name"    => "",
                "nobility_picture" => "",
                "nickname"         => "",
                "head_picture"     => "",
            ];
        }
        $user                 = app('model_user_data')->where('user_id', $user_id)->select(['nickname', 'head_picture'])->first();
        $info['nickname']     = $user->nickname ?? '';
        $info['head_picture'] = $user->head_picture ?? '';

        return ['info' => $info, 'renew' => $renew, 'rank_info' => app('model_user')->rankInfo($user_id)];
    }*/

    public function nobilityInfo($user_id)
    {
        $user_nobility = app('model_user_nobility')->getUserNobility($user_id);
        $user_nobility = $user_nobility ?? [];
        $user_nobility_list = app('model_user_nobility')->where([
            'user_id' => $user_id, 'state' => 1,
        ])->selectRaw('nobility_id,expired_time,renew_time')->get()->toArray();
        #根据等级升序排序 -- 别动
        $user_nobility_list = array_column($user_nobility_list, NULL, 'nobility_id');
        $nobility = app('model_nobility')->orderBy('grade', 'asc')->get()->toArray();
        $nobility_grade = array_column($nobility, NULL, 'grade');
        #最高等级的爵位
        $end_nobility = end($nobility_grade);
        $nobility_privilege_list = app('model_nobility_privilege')->select([
            'id', 'name', 'desc', 'head_picture', 'dark_picture', 'image'
        ])->orderBy('sort', 'asc')->get()->toArray();
        $privilege_length = count($nobility_privilege_list);

        $nobility_expire_day = app('repo_nobility')->getExpireDay();
        $end_time = time();
        $today = date('Y-m-d');
        $repo_nobility = app('repo_nobility');
        $begin_start_time = $end_time - $nobility_expire_day * 86400;
        $next_between_date = [$begin_start_time, $end_time];
        foreach ($nobility as &$value) {
            $is_last = 0;
            $start_time = $begin_start_time;
            if ($end_nobility['grade'] == $value['grade']) {
                $is_last = 1;
            }
            $value['is_last'] = $is_last;
            $privilege_ary = explode(',', $value['privilege']);
            $count = $value['privilege'] ? count($privilege_ary) : 0;
            $value['private_rate'] = $count . '/' . $privilege_length;
            $user_nobility_info = null;//用户的爵位信息
            if (isset($user_nobility_list[$value['id']])) {
                $user_nobility_info = $user_nobility_list[$value['id']];
                $user_nobility_info['expired_time'] = dateDiff($today, date('Y-m-d', $user_nobility_info['expired_time']), 'days');
                $start_time = $user_nobility_info['renew_time'];
            }
            #获取用户充值/消费金币  爵位升级所需的费用
            $between_date = [$start_time, $end_time];
            $value['sum_gold'] = $repo_nobility->userSumGold($user_id, $value['type'], $between_date);

            $next_grade = $value['grade'] + 1;
            if (!empty($user_nobility_info)) {
                //下次升级 返回参数  下次升级的金额/
                $user_nobility_info['next_grade_name'] = '';
                $next_grade_name = $next_diff = $next_rate = '';
                $next_nobility = $nobility_grade[$next_grade] ?? [];
                $next_status = 0;
                if (!empty($next_nobility) && $user_nobility['grade'] < $next_nobility['grade']) {
                    $next_status = 1;
                    $next_grade_name = $next_nobility['name'];
                    $next_sum_gold = $repo_nobility->userSumGold($user_id, $next_nobility['type'], $next_between_date);
                    $next_sum_gold = $next_sum_gold > $next_nobility['price'] ? $next_nobility['price'] : $next_sum_gold;
                    $next_diff = $next_nobility['price'] - $next_sum_gold;
                    $next_rate = number_format($next_sum_gold / $next_nobility['price'], 2);
                }
                $user_nobility_info['next_status'] = $next_status;
                $user_nobility_info['next_grade_name'] = $next_grade_name;
                $user_nobility_info['next_diff'] = $next_diff;
                $user_nobility_info['next_rate'] = $next_rate;
                //续费比例参数 1:消费 2充值，为1时=>消费金币已查询过 否则新查询一次
                if ($value['type'] == 1) {
                    $renew_gold = $value['sum_gold'];
                } else {
                    $renew_gold = $repo_nobility->userSumGold($user_id, 1, $between_date);
                }
                $renew_gold = $value['renew'] < $renew_gold ? $value['renew'] : $renew_gold;
                $rate = number_format($renew_gold / $value['renew'], 2);
                $user_nobility_info['rate'] = $rate;
                $user_nobility_info['rate_gold'] = $value['renew'] - $renew_gold;
            }
            $value['user_nobility_info'] = $user_nobility_info;
            $nobility_privilege = $nobility_privilege_list;
            foreach ($nobility_privilege as &$privilege) {
                if ($value['privilege'] && in_array($privilege['id'], $privilege_ary)) {
                    $privilege['is_exist'] = 1;
                } else {
                    $privilege['is_exist'] = 0;
                    $privilege['head_picture'] = $privilege['dark_picture'];
                }
                unset($privilege['dark_picture']);
            }
            $value['nobility_privilege'] = $nobility_privilege;
        }
        $result = [
            'nobility_info' => $nobility,
        ];
        return $result;
    }

    //提现
    public function userWithDraw($number, $bank_id, $user_id, $type = 1)
    {
        $existsBlock = WithdrawBlock::query()->where('user_id', $user_id)->exists();
        if ($existsBlock) {
            throw new BasicException(-1, '当前用户不允许提现');
        }
        // 判断是否为 公会用户是的才能体现
        $model_sc_sociaty_user = app('model_sc_sociaty_user')->where('user_id', $user_id)->exists();
        if (!$model_sc_sociaty_user) {
            throw new BasicException(-1, '需要签约才能提现哦~');
        }
        $userModel = app('model_user');
        $user_info = $userModel->where('user_id', $user_id)->select([
            'earnings', 'earnings_status', 'second_password', 'earnings_coin', 'channel_no',
        ])->first();
        if (!$user_info) {
            throw new BasicException(40014, '用户信息有误');
        }
        //用户加入公会才能提现
        $is_withdraw = app('model_config')->getValue('GUILD_WITHDRAW');
        if ($is_withdraw) {
            $is_exist = app('model_sc_sociaty_user')->where(['user_id' => $user_id])->count();
            if (!$is_exist) {
                throw new BasicException(-1, '请先加入公会');
            }
        }

        if ($user_info->earnings_status == 0) {
            throw new BasicException(80015, '账户收益被冻结');
        }
        $dayMaxCount = app('model_config')->getValue('DAY_MAX_COUNT') ?: 3;
        if ((RedisService::getUserWithdrawTimes($user_id) >= $dayMaxCount)) {
            throw new BasicException(80004, "每日提现最多只能{$dayMaxCount}次");
        }

        //某些渠道的用户，只有充值过才能提现
        $limit_channel = app('model_config')->getValue('LIMIT_CHANNEL');

        if (!empty($limit_channel)) {
            $total_recharge = app('model_user_recharge')->getUserRechargeGold($user_id);
            if ($total_recharge <= 0 && in_array($user_info['channel_no'], $limit_channel)) {
                throw new BasicException(80005, '不符合提现条件');
            }
        }

        $second_password = app('request')->input('password');
        if ($second_password) {
            if (!$user_info['second_password']) {
                throw new BasicException(80006, '请先设置二级密码');
            }

            if (!pwdHash($second_password, $user_info['second_password'], true)) {
                throw new BasicException(80007, '二级密码错误');
            }
        }

        $bank_info = app('model_user_bank')->where('id', $bank_id)->first();
        if (!$bank_info || $bank_info['user_id'] != $user_id) {
            throw new BasicException(80008, '银行卡不存在');
        }

        $money = $user_info['earnings'];
        $gold_fee = app('model_config')->getValue('GOLD_FEE');
        if ($number > ($money / $gold_fee)) {
            throw new BasicException(80014, '可提现金额不足');
        }
        if ($number < 100) {
            throw new BasicException(80009, '提现金额不能小于100元');
        }
        if (ceil($number) != $number || $number % 10) {
            throw new BasicException(80010, '提现金额必须为10的整数倍');
        }

        if ($bank_info['bank_type'] == 3 && $number < 100) {
            throw new BasicException(-1, '银行卡100起提');
        }

        $user_auth = app('model_user_auth')->where(['user_id' => $user_id, 'app_status' => 1])->first();
        if (!$user_auth) {
            throw new BasicException(80011, '请先实名认证');
        }

        //1单支付宝用户每月9w； 2多支付宝用户每个支付宝每月9w
        $user_bank_count = app('model_user_bank')->where(['user_id' => $user_id, 'bank_type' => 1])->count();
        if ($user_bank_count == 1) {
            if ($bank_info['cardholder'] != $user_auth['full_name']) {
                throw new BasicException(80012, '支付宝提现账号必须同实名认证名字一致才可提现');
            }
            $where_sum = ['user_id' => UID];
        } else {
            $where_sum = ['bank_num' => $bank_info['bank_num']];
        }
        $total_withdraw_month = app('model_user_withdraw')->getWithdrawMonth($where_sum);
//        if (($total_withdraw_month + $number) > 90000) {
//            throw new BasicException(80013, '当月提现金额不能超过9万');
//        }

        $withdrawFeeRate = app('model_config')->getValue('WITHDRAW_CHARGED_FEE');
        $withdrawFeeRate = $withdrawFeeRate ?? 2;
        $withdrawFee = floor($number * $withdrawFeeRate / 100);
        if ($withdrawFee < 0) {
            throw new BasicException(-1, '提现费用异常，请联系管理员');
        }

        //事务
        $gold = $number * $gold_fee;
        DB::beginTransaction();
        $data['gold'] = $gold;
        $data['apply_money'] = $number;
        $data['charged_fee'] = $withdrawFee;
        $data['money'] = $number - $withdrawFee;
        $data['user_id'] = UID;
        $data['bank_id'] = $bank_id;
        $data['bank_type'] = $bank_info['bank_type'];
        $data['bank_num'] = $bank_info['bank_num'];
        $data['cardholder'] = $bank_info['cardholder'];
        $data['card_number'] = $bank_info['card_number'];
        $data['bank_name'] = $bank_info['bank_name'];
        $data['bank_zhi'] = $bank_info['bank_zhi'];
        $data['mobile'] = $bank_info['mobile'];
        $data['add_time'] = time();
        $data['type'] = $type;
        if ($user_info['earnings_coin'] >= $gold) {
            $data['coin'] = $gold;
        } else {
            $data['coin'] = $user_info['earnings_coin'];
        }

        $id = app('model_user_withdraw')->insertGetId($data);
        //操作用户金额
        $_where = [
            'user_id' => $user_id,
            ['earnings', '>=', $gold],
            ['earnings_coin', '>=', $data['coin']],
        ];
        $re = $userModel->where($_where)->update([
            'earnings' => DB::raw('earnings - ' . $gold),
            'earnings_coin' => DB::raw('earnings_coin - ' . $data['coin']),
            'freeze_money' => DB::raw('freeze_money + ' . $gold),
        ]);
        if ($id && $re) {
            app('model_account_log')->addData($user_id, $gold, "提现中", 23, 0, 0, $id);
            RedisService::incUserWithdrawTimes($user_id);
            DB::commit();

            return true;
        } else {
            DB::rollback();
            throw new BasicException(80013, '提现失败');
        }
    }

    public function rongCloudToken($userId)
    {
        $model = app('model_user_data')->where('user_id', $userId)->first();
        $result = app('rongcloud')->createUser($model->user_id, $model->nickname, $model->head_picture);
        if ($result['code'] !== 200) {
            throw new BasicException(0, '生成 Token 失败');
        }
        app('model_user')->where('user_id', $model->user_id)->update(['ry_token' => $result['token']]);

        return [
            'token' => $result['token'],
        ];
    }

    public function getNobilityList($user_id)
    {
        $userNobility = app('model_user_nobility')->getUserNobility($user_id);
        $list = app('model_nobility');
        if ($userNobility) {
            $list = $list->where('id', '>=', $userNobility->nobility_id);
        }
        $list = $list->orderBy('price', 'asc')->get();
        if (!$list->isEmpty()) {
            $list = $list->toArray();
            $gold = app('model_config')->getValue('GOLD_FEE');
            foreach ($list as $key => $value) {
                $list[$key]['price'] = $value['price'] * $gold;
                $list[$key]['renew'] = $value['renew'] * $gold;
                $list[$key]['rebate'] = $value['price'] * $gold * $value['rebate'] / 100;
            }
        } else {
            $list = [];
        }

        return $list;
    }

    public function rebateGiftUser(int $userId, bool $lock = false)
    {
        $query = User::query();
        if ($lock) {
            $query->lockForUpdate();
        }
        $query->with(['user_data', 'rebate_gift']);
        $query->where(['user_id' => $userId]);
        $model = $query->first();
        $model->rebate_gift->input = $model->rebate_gift->input ?? 0;
        $model->rebate_gift->output = $model->rebate_gift->output ?? 0;
        $model->rebate_gift->profit = $model->rebate_gift->output - $model->rebate_gift->input;
        return $model;
    }

    public function search(int $userCode)
    {
        if (empty($userCode)) {
            return new Collection();
        }
        return UserData::query()
            ->select(['user_code', 'head_picture', 'user_id', 'nickname'])
            ->where('user_code', 'like', "{$userCode}%")
            ->limit(10)
            ->get();
    }


    // 批量用户收入
    public function batchUpdateUserEarnings(array $earningList)
    {
        if (empty($earningList)) {
            return true;
        }

        $userIds = array_keys($earningList);
        $userIdStr = implode(',', $userIds);

        $table = app('model_user')->getTable();
        $sql = "update {$table} set ";
        // 增加数量
        $sql .= "`earnings` = case ";
        foreach ($earningList as $userId => $earning) {
            $sql .= "when user_id = {$userId}  then `earnings` + {$earning} ";
        }
        $sql .= "else `earnings` end ";
        // 条件
        $sql .= " where  user_id in ($userIdStr)";
        return DB::update($sql);
    }

    public function getMaxUserId($filter)
    {
        $maxUserId = app('redis')->get("user:max_user_id");
        if (empty($maxUserId)) {

            $maxUserId = User::query()->from('ln_user_data as a')->selectRaw('max(user_id) as max_user_id')
                ->where('intro_voice_time', '>', 0)
                ->first(['max_user_id'])->max_user_id;

            app('redis')->set("user:max_user_id", $maxUserId, 'EX', 24 * 3600);
        }
        return $maxUserId;
    }

    public function getOnlineVoiceUsers()
    {
        return UserData::query()
            ->leftJoin("ln_user as u", "u.user_id", '=', 'ln_user_data.user_id')
            ->where("intro_voice_time", ">", 0)
            ->where("u.deleted", 0)
            ->where("u.offline_time", 0)
            ->pluck("u.user_id");
    }

    public function getRandListWithData(array $filters, array $fields, int $count, $userId = 0, $order_rand = false)
    {
        $fields = [
            'ln_user_data.user_id',
            'ln_user_data.head_picture',
            'ln_user_data.birthday',
            'ln_user_data.signature',
            'gc.head_picture as level_icon',
            'constellation',
            'city_id',
//            DB::raw('0 as offline_time'),
            'intro_voice_time',
            'nickname',
            'sex',
            'user_code',
            'intro_voice',
            'rank_id',
            'charm_id',
            'nobility',
            'offline_time',
            'register_time',
        ];
        try {
            $data = UserData::query()
                ->select($fields)
                ->where($filters)
                ->leftJoin('ln_user as u', 'ln_user_data.user_id', '=', 'u.user_id')
                ->leftJoin('ln_grade_config as gc', 'u.rank_id', '=', 'gc.id')
                ->where('u.user_id', '<>', $userId)
                ->limit($count);
            if ($order_rand) {
                $data->inRandomOrder();
            } else {
                $data->orderBy('u.user_id', 'desc');
            }
            return $data->get();
        } catch (\Throwable $e) {
            print_r($e->getMessage());
        }


        $userIds = RedisService::getOnlineVoiceUserIds($count);
        return UserData::query()
            ->select($fields)
            ->leftJoin('ln_user as u', 'ln_user_data.user_id', '=', 'u.user_id')
            ->leftJoin('ln_grade_config as gc', 'u.rank_id', '=', 'gc.id')
            ->whereIn("ln_user_data.user_id", $userIds)
            ->get();

        $maxUserId = $this->getMaxUserId($filters) - $count > 0 ? ($this->getMaxUserId($filters) - $count) : 0;
        return User::query()->select($fields)
            ->join('ln_user_data as ud', 'ln_user.user_id', '=', 'ud.user_id')
            ->leftJoin('ln_grade_config as gc', 'ln_user.rank_id', '=', 'gc.grade')
            ->where($filters)
            ->whereRaw("ln_user.user_id > " . rand(0, $maxUserId - $count))
            ->limit($count)
            ->get();
    }

    public function isSetIntroVoice($userId)
    {

    }

    public function userTodayOnlineSecond(int $userId): int
    {
        $yesterdayStart = Carbon::now()->addDays(-1)->startOfDay()->timestamp;
        $yesterdayEnd = Carbon::now()->addDays(-1)->endOfDay()->timestamp;
        $dayStart = Carbon::now()->startOfDay()->timestamp;

        $second = 0;
        // 已记录的在线时长
        $records = app("model_room_join_time")->newQuery()
            ->where("user_id", $userId)
            ->where("join_time", ">=", $yesterdayStart)
            ->where("left_time", ">=", $yesterdayEnd)
            ->select(["left_time", "join_time", "total_seconds"])
            ->get();
        foreach ($records as $record) {
            if ($record->join_time < $dayStart) {
                $second += $record->left_time - $dayStart;
            } else {
                $second += $record->total_seconds;
            }
        }

        // 未记录的在线时长
        $online = app("model_room_online_user")->newQuery()
            ->where("user_id", $userId)
            ->where("room_id", ">", 0)
            ->select(["join_time"])
            ->first();
        if ($online) {
            $second += time() - $online->join_time;
        }

        return (int)$second;
    }

    public function userRechargeCoin(int $userId, int $startTime = 0, int $endTime = 0)
    {
        $query = app("model_user_recharge")->newQuery();
        $query->where("user_id", $userId);
        $query->where("status", 2);
        if ($startTime != 0) {
            $query->where("add_time", ">=", $startTime);
        }
        if ($endTime != 0) {
            $query->where("add_time", "<=", $endTime);
        }
        return $query->sum("gold");
    }

    public function incUserMoney(int $userId, int $coin)
    {
        if ($coin <= 0) {
            throw new BasicException(-1, "金额错误");
        }

        $res = User::query()->where("user_id", $userId)->update([
            "money" => DB::raw('money + ' . $coin),
        ]);
        if (!$res) {
            throw new BasicException(-1, "金币充值失败");
        }
    }

    public function decUserMoney(int $userId, int $coin)
    {
        if ($coin <= 0) {
            throw new BasicException(-1, "金额错误");
        }
        $user = User::query()->where('user_id', $userId)->lockForUpdate()->firstOrFail();
        if ($user->money < $coin) {
            throw new BasicException(-1, '用户金币不足');
        }


        $res = User::query()->where("user_id", $userId)->update([
            "money" => DB::raw('money - ' . $coin),
        ]);
        if (!$res) {
            throw new BasicException(-1, "扣费失败");
        }
    }

    /**
     * 设置用户当前所在城市
     *
     * @param int $userId 用户id
     * @param string $ip ip地址
     * @param int $expire 过期时间/秒
     *
     * @return int
     */
    public function setUserCurrentCity(int $userId, string $ip = "", int $expire = 3600): int
    {
        try {
            $lock = RedisService::setUserCurrentCityLock($userId, $expire);
            if (!$lock) {
                throw new BasicException(-1, "请稍后再试");
            }
            if (empty($ip)) {
                $ip = UserDevice::query()->where(['user_id' => $userId])->orderBy('id', 'desc')->value("ip");
            }
            if (empty($ip)) {
                throw new BasicException(-1, "未获取到用户ip");
            }

            $server = new AmapService();
            $res = $server->getRegionByIp($ip);
            if ($res->status != 1 || empty($res->infocode)) {
                throw new BasicException(-1, "请求失败");
            }

            // 获取城市id
            $cityId = Region::query()->where("region_code", $res->adcode)->value("id");
            $cityId = (int)$cityId;
            if (!$cityId) {
                throw new BasicException(-1, "城市不存在");
            }

            // 更新当前城市id
            UserData::query()->where("user_id", $userId)->update(["current_city_id" => $cityId]);
        } catch (\Exception $e) {
            RedisService::refreshUserCurrentCityLock($userId);
            return 0;
        }

        return $cityId;


    }


    public function userOnlineSecond(int $userId)
    {
        $res = $this->usersOnlineSecond([$userId]);
        return $res[$userId] ?? 0;
    }

    public function usersOnlineSecond(array $userIds, int $minute = 0): array
    {
        // 当前所在房间
        $nowRooms = RoomOnlineUser::query()
            ->whereIn("user_id", $userIds)
            // ->whereIn("room_id", $allowRoomIds)
            ->get();

        // 推出房间时长
        $quitRoomOnline = RoomJoinTime::query()
            ->groupBy(["user_id"])
            ->select(["user_id", DB::raw("total_seconds as seconds")])
            ->whereIn("user_id", $userIds)
            // ->whereIn("room_id", $allowRoomIds)
            ->where("join_time", ">=", Carbon::now()->startOfDay()->timestamp)
            ->get();

        $res = [];
        foreach ($userIds as $userId) {
            $nowSecond = 0;
            $quitSecond = $quitRoomOnline->where("user_id", $userId)->sum("seconds");
            $nowRoom = $nowRooms->where("user_id", $userId)->first();
            if ($nowRoom) {
                $nowSecond = time() - $nowRoom->join_time;
                if ($nowRoom->join_time <= Carbon::now()->startOfDay()->timestamp) { // 今天之前进的房间
                    $nowSecond = time() - Carbon::now()->startOfDay()->timestamp;
                }
            }
            $second = $nowSecond + $quitSecond;
            $res[$userId] = $second;
        }
        return $res;
    }

    public function getOtherUserInfo($userId)
    {
        return UserData::query()
            // ->select(['ln_user_data.user_id', 'ln_user_data.nickname', 'ln_user_data.sex', 'ln_user_data.head_picture as avatar', 'ln_user_data.anchor_type', 'skill', 'charm_level', 'wealth_level', 'ln_user_data.user_code'])
            ->select(['ln_user_data.user_id', 'ln_user_data.nickname', 'ln_user_data.sex', 'ln_user_data.head_picture as avatar', 'ln_user_data.anchor_type', 'skill', 'ln_user_data.user_code'])
            ->leftJoin('ln_anchor_apply as aa', 'aa.user_id', '=', 'ln_user_data.user_id')
            ->where('ln_user_data.user_id', $userId)
            ->first();
    }

    public static function anchorIcon($skill, $anchorType)
    {
        $icon = '';
        if ($skill == AnchorEnum::SKILL_CHAT) { //疗愈师
            switch ($anchorType) {
                case 1:
                    $icon = AnchorEnum::ANCHOR_LEVE_COIN_HEALING_1;
                    break;
                case 2:
                    $icon = AnchorEnum::ANCHOR_LEVE_COIN_HEALING_2;
                    break;
                case 3:
                    $icon = AnchorEnum::ANCHOR_LEVE_COIN_HEALING_3;
                    break;
                case 4:
                    $icon = AnchorEnum::ANCHOR_LEVE_COIN_HEALING_4;
                    break;
                default:
                    break;
            }

        } elseif ($skill == AnchorEnum::SKILL_SINGER) { //歌手
            switch ($anchorType) {
                case 1:
                    $icon = AnchorEnum::ANCHOR_LEVE_COIN_SINGER_1;
                    break;
                case 2:
                    $icon = AnchorEnum::ANCHOR_LEVE_COIN_SINGER_2;
                    break;
                case 3:
                    $icon = AnchorEnum::ANCHOR_LEVE_COIN_SINGER_3;
                    break;
                case 4:
                    $icon = AnchorEnum::ANCHOR_LEVE_COIN_SINGER_4;
                    break;
                default:
                    break;
            }

        }
        return $icon;

    }

    //获取用户冠名信息
    public function getUserTitleNowInfo($userId)
    {
        $now_info = RedisService::getUserTitleNow($userId, -1);
        if (empty($now_info)) {
            return null;
        }

        $gift_info = RedisService::getGiftInfo($now_info[3]);
        return [
            'title' => $now_info[2],
            'color' => GiftEnum::TITLE_GIFT_COLOR[$now_info[1]],
            'gift_picture' => $gift_info['picture'] ?? '',
        ];
    }

    // 随机生成一个code
    static function generateRandomCode($length = 32)
    {
        // 生成随机字节
        $bytes = random_bytes($length);
        // 将字节转换为十六进制字符串
        return bin2hex($bytes);
    }

    // 随机生成一个token
    static function generateRandomToken($userId, $length = 64)
    {
        // 生成随机字节
        $bytes = random_bytes($length);
        // 将字节转换为十六进制字符串
        $bytes = $userId . $bytes;
        return bin2hex($bytes);
    }

    /**
     * 小游戏获取token
     */
    public function giCode($userId)
    {
        // 我们这边生成一个code 存入数据库 和redis
        $code = self::generateRandomCode();
        $token = self::generateRandomToken($userId);
        User::query()->where('user_id', $userId)->update([
            'gi_code' => $code,
            'ss_token' => $token,
        ]);
        // 更新 redis
        app('redis')->hset(sprintf(RedisKeyEnum::USER_INFO, $userId), 'gi_code', $code);
        app('redis')->hset(sprintf(RedisKeyEnum::USER_INFO, $userId), 'ss_token', $token);
        return [
            'code' => $code,
            'token' => $token
        ];
    }
}
